记录一下这个难过的双休,2019.3.16-2019.3.17,16号上午字节跳动笔试,四道题只做出1道半,输入输出搞的半死,第三题类似于leetcode上的分糖问题,数组初始化的时候全部赋为0了,要是赋维1就做出来了,唉,气死了。17号下午做两道深搜的题目,全都死在java引用上面了,卡了一下午多,现在想想c++的指针是多么的方便。

  下午的两道题分别是牛客网和leetcode上的深度优先搜索,这两道题套路完全一样。

  1.二叉树中和为某一值的路径:输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)

  这道题的解法详见下面,其中有个问题就是java中值和址的问题。

  这里要详细说明。首先如果传的是int等基本数据类型和string,那么你使用下面的方法是改变不了a的值的:

 class Solution{
public void fun(int a){
a++;
}
public static void main(String []args){
int a=1;
fun(a);
System.out.println(a);
//这里会输出a=1
}
}

  而其他的类都是传地址的,也就是说在函数外面定义TreeNode1=root,函数定义fun(TreeNode2){},这时候其实两个TreeNode是不一样的两个东西,只是指向的东西一样而已。也就是说你在函数里面是有可能改变这个类里面的某些属性的,比如在函数里面写TreeNode2.val=2,那么真正的val真的变成了2。但是如果你在函数里面令TreeNode2=root2,那么只是函数里面的TreeNode2换了一个东西指了而已,函数外面的TreeNode1还是指向的root。

  例如在ArrayList<ArrayList<Integer>> ans中加入一个ArrayList temp,先add一个为【1,2】的temp,然后改变temp,变为【1,2,3】,再add。但是这时候ans里面的数据是【1,2,3】【1,2,3】,为什么呢,因为temp传的是地址,也就是说当temp改变为【1,2,3】之后,其实是temp指向的那块地方的东西变成了【1,2,3】,所以之前已经add进ans的数据也一起改变为【1,2,3】了。要解决这个问题,就要在每次add前新建一个ArrayList,把temp克隆过去clone,这样的话每个ArrayList指向的就是两个地址,其中一个改变不会影响令一个。

 import java.util.ArrayList;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null; public TreeNode(int val) {
this.val = val; } }
*/
public class Solution {
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
if(root==null)
return new ArrayList<ArrayList<Integer>>();
ArrayList<ArrayList<Integer>> ans =new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> temp=new ArrayList<Integer>();
help(root,target,ans,temp);
//System.out.println(ans.get(0).size()); for(int i=0;i<ans.size();i++){
for(int j=i+1;j<ans.size();j++){
if(ans.get(j).size()>ans.get(j).size()){
ArrayList<Integer> temp2;
temp2=ans.get(j);
ans.set(j,ans.get(i));
ans.set(i,temp2);
} }
}
return ans;
}
void help(TreeNode root,int target,ArrayList<ArrayList<Integer>> ans,ArrayList<Integer> temp){
//System.out.println("aaaa");
if(root==null){
//temp.remove(temp.size()-1);
return;
}
temp.add(root.val); if(root.val==target && root.right==null && root.left==null){
ArrayList<Integer> te=new ArrayList<Integer>();
te=(ArrayList<Integer>)temp.clone();
ans.add(te);
temp.remove(temp.size()-1);
return;
}
if(root.val!=target && root.right==null && root.left==null){
temp.remove(temp.size()-1);
return;
}
help(root.left,target-root.val,ans,temp);
help(root.right,target-root.val,ans,temp);
temp.remove(temp.size()-1);
return; }
}

  2.79:Given a 2D board and a word, find if the word exists in the grid.The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

  这道题有两个坑,一个是if(i>=0 && i<board.length && j>=0 && j<board[0].length && board[i][j]==word.charAt(num) && flag[i][j]==0)中,有可能会造成数组越界的判断条件放前面,不然会造成数组越界。第二个,如果你想减少一部分java引用带来的困扰,就要使用回溯法,这点很重要。

 class Solution3 {
int ans=0;
public boolean exist(char[][] board, String word) {
int n=board.length;
int m=board[0].length;
int[][] flag3=new int [n][m];
int num=0;
if(n==0)
return false;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
help(board, i, j, word,flag3,num);
if(ans==1)
return true;
}
}
return false;
}
void help(char[][] board,int i,int j,String word,int[][] flag,int num2){
//int [][] flag=(int [][])flag2.clone(); int num=num2; if(i>=0 && i<board.length && j>=0 && j<board[0].length && board[i][j]==word.charAt(num) && flag[i][j]==0){
flag[i][j]=1;
num++;
if(num==word.length()){
ans=1;
return ;
} help(board, i+1, j, word, flag, num);
if(ans==1)
return ;
help(board, i-1, j, word, flag, num);
if(ans==1)
return ;
help(board, i, j+1, word, flag, num);
if(ans==1)
return ;
help(board, i, j-1, word, flag, num);
flag[i][j]=0; }
else
return ; } public static void main(String []args){
Solution3 s=new Solution3();
char [][] c={{'C','A','A'},{'A','A','A'},{'B','C','B'}};
String str="AAB";
System.out.println(s.exist(c,str));
}
}

  

java中函数传值和传地址的问题的更多相关文章

  1. java中的传值与传引用

    java函数中的传值和传引用问题一直是个比较“邪门”的问题,其实java函数中的参数都是传递值的,所不同的是对于基本数据类型传递的是参数的一份拷贝,对于类类型传递的是该类参数的引用的拷贝,当在函数体中 ...

  2. java中函数传值与引用问题

    从C++转java,在使用函数传对象时,碰到一点问题,今天特意验证了一下: public class App { public static void doubleTest(double d) { d ...

  3. 一段代码让你秒懂java方法究竟是传值还是传地址

    先看看代码以及执行结果: 凝视写得非常清楚了.我就不多说了. 我说说我的结论.事实上在java中没有传值还是传址的概念,java仅仅有引用的概念.引用类似传址.只是是一个变量名中保存着对象的地址,地址 ...

  4. Java中的值传递和地址传递(传值、传引用)

    首先,不要纠结于 Pass By Value 和 Pass By Reference 的字面上的意义,否则很容易陷入所谓的“一切传引用其实本质上是传值”这种并不能解决问题无意义论战中.更何况,要想知道 ...

  5. python中传值和传地址问题

    在python中,还没有对这个知识点有一个详细的定义,很模糊的说明了,通过下面代码,可以观察出来,什么时候传的是值,什么时候传的是地址 有时候会发现自己的数据发生变化,可能就是这个原因,python的 ...

  6. C/C++中传值和传地址(引用)

    C/C++中参数传递有两种方式,传值或传地址(传引用),通常我们要在被调用函数中改变一个变量的值就需要传地址调用方式,例如: void swap_by_value(int a, int b) { in ...

  7. Java中使用HttpPost上传文件以及HttpGet进行API请求(包含HttpPost上传文件)

    Java中使用HttpPost上传文件以及HttpGet进行API请求(包含HttpPost上传文件) 一.HttpPost上传文件 public static String getSuffix(fi ...

  8. JAVA中使用FTPClient上传下载

    Java中使用FTPClient上传下载 在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件.下载文件,本文简单介绍如何利用jakarta commons中的FTPClient(在c ...

  9. java 中函数的参数传递详细介绍

    java中函数的参数传递 总结: 1.将对象(对象的引用)作为参数传递时传递的是引用(相当于指针).也就是说函数内对参数所做的修改会影响原来的对象.  2.当将基本类型或基本类型的包装集作为参数传递时 ...

随机推荐

  1. spoj gss1 gss3

    传送门 gss1 gss3 spoj gss系列=最大字段和套餐 gss1就是gss3的无单点修改版 有区间查询和单点修改,考虑用线段树维护 我们要维护区间权值和\(s\),区间最大前缀和\(xl\) ...

  2. tomcat顺序图摘要

    1.Connector 处理一次请求顺序图 2.Context 和 wrapper 的处理请求时序图 3. 参考: https://www.ibm.com/developerworks/cn/java ...

  3. k8s系列~mgr的应用

    一  简介:今天咱们大体介绍下 这两者是如何联系的二  概念解析     pod:说下我的理解    1 pod通过yaml文件来封装docker本身+启动形式    2 pod可以运行多个docke ...

  4. JavaScript中Function的拓展

    Function 是什么东西,就是JavaScript中的顶级类,系统级别的类.我们平时写的函数方法例如下. function Animal() { } Animal就是Function的实例,但是在 ...

  5. vc++调用exe获取输出信息

    目的 调用命令行程序,返回结果. 思路 把命令行结果输入到管道中,exe的输出信息都存在了strOutput这个变量里. 实现代码 CString strCmd = L"yara64.exe ...

  6. 对HUAWEI-ManagedProvisioning的一次不完整分析

    分析思路 关注点1:AndroidManifest.xml是Android应用的入口文件,包含有APP服务的权限.广播和启动位置. 关注点2:涉及到修改系统的函数,setWifiEnabled().I ...

  7. 【Python】zip文件密码破解

    掌握基础语法后,尝试使用python的zipfile模块练手. zipfile是Python里用来做zip格式编码的压缩和解压缩的. 这里将大体的思路分解成四段代码,逐一完善功能: 第一段代码:解压z ...

  8. UML和模式应用5:细化阶段(10)---UML交互图

    1.前言 UML使用交互图来描述对象间消息的交互 交互图可以用于动态对象建模. 交互图有两种类型:顺序图和通信图. UML交互图将用来解释和阐述对象设计. 2.顺序图和通信图 顺序图具有丰富的符号标记 ...

  9. python实现监控windows服务控制开关服务

    转载自 :http://www.jb51.net/article/49106.htm #!/usr/bin/env python #-*- encoding:utf-8 -*- "" ...

  10. crontab定时作业

    crontab用于在指定时间执行某项作业,如执行脚本或命令. 1.crontab -e      创建一个crontab文件,并添加作业(这个crontab的拥有者是创建者). 这里要注意:必须指定s ...