java中函數傳值和傳地址的問題


  記錄一下這個難過的雙休,2019.3.16-2019.3.17,16號上午字節跳動筆試,四道題只做出1道半,輸入輸出搞的半死,第三題類似於leetcode上的分糖問題,數組初始化的時候全部賦為0了,要是賦維1就做出來了,唉,氣死了。17號下午做兩道深搜的題目,全都死在java引用上面了,卡了一下午多,現在想想c++的指針是多么的方便。

  下午的兩道題分別是牛客網和leetcode上的深度優先搜索,這兩道題套路完全一樣。

  1.二叉樹中和為某一值的路徑:輸入一顆二叉樹的跟節點和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。路徑定義為從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。(注意: 在返回值的list中,數組長度大的數組靠前)

  這道題的解法詳見下面,其中有個問題就是java中值和址的問題。

  這里要詳細說明。首先如果傳的是int等基本數據類型和string,那么你使用下面的方法是改變不了a的值的:

 1 class Solution{
 2     public void fun(int a){
 3         a++;
 4     }
 5     public static void main(String []args){
 6         int a=1;
 7         fun(a);
 8         System.out.println(a);
 9         //這里會輸出a=1
10     }
11 }

  而其他的類都是傳地址的,也就是說在函數外面定義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指向的就是兩個地址,其中一個改變不會影響令一個。

 1 import java.util.ArrayList;
 2 /**
 3 public class TreeNode {
 4     int val = 0;
 5     TreeNode left = null;
 6     TreeNode right = null;
 7 
 8     public TreeNode(int val) {
 9         this.val = val;
10 
11     }
12 
13 }
14 */
15 public class Solution {
16     public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
17         if(root==null)
18             return new ArrayList<ArrayList<Integer>>();
19         ArrayList<ArrayList<Integer>> ans =new ArrayList<ArrayList<Integer>>();
20         ArrayList<Integer> temp=new ArrayList<Integer>();
21         help(root,target,ans,temp);
22         //System.out.println(ans.get(0).size());
23 
24         for(int i=0;i<ans.size();i++){
25             for(int j=i+1;j<ans.size();j++){
26                 if(ans.get(j).size()>ans.get(j).size()){
27                     ArrayList<Integer> temp2;
28                     temp2=ans.get(j);
29                     ans.set(j,ans.get(i));
30                     ans.set(i,temp2);
31                 }
32 
33             }
34         }
35         return ans;
36     }
37     void help(TreeNode root,int target,ArrayList<ArrayList<Integer>> ans,ArrayList<Integer> temp){
38         //System.out.println("aaaa");
39         if(root==null){
40             //temp.remove(temp.size()-1);
41             return;
42         }
43         temp.add(root.val);
44        
45         if(root.val==target && root.right==null && root.left==null){   
46             ArrayList<Integer> te=new ArrayList<Integer>();
47             te=(ArrayList<Integer>)temp.clone();
48             ans.add(te);
49             temp.remove(temp.size()-1);
50             return;
51         }
52         if(root.val!=target && root.right==null && root.left==null){
53             temp.remove(temp.size()-1);
54             return;
55         }
56         help(root.left,target-root.val,ans,temp);
57         help(root.right,target-root.val,ans,temp);
58         temp.remove(temp.size()-1);
59         return;
60 
61 
62     }
63 }

  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引用帶來的困擾,就要使用回溯法,這點很重要。

 1 class Solution3 {
 2     int ans=0;
 3     public boolean exist(char[][] board, String word) {
 4         int n=board.length;
 5         int m=board[0].length;
 6         int[][] flag3=new int [n][m];
 7         int num=0;
 8         if(n==0)
 9             return false;
10         for(int i=0;i<n;i++){
11             for(int j=0;j<m;j++){
12                 help(board, i, j, word,flag3,num);
13                 if(ans==1)
14                     return true;
15             }
16         }
17         return false;
18     }
19     void help(char[][] board,int i,int j,String word,int[][] flag,int num2){
20         //int [][] flag=(int [][])flag2.clone();
21 
22         int num=num2;
23 
24         if(i>=0 && i<board.length && j>=0 && j<board[0].length && board[i][j]==word.charAt(num) && flag[i][j]==0){
25             flag[i][j]=1;
26             num++;
27             if(num==word.length()){
28                 ans=1;
29                 return ;
30             }
31 
32             help(board, i+1, j, word, flag, num);
33             if(ans==1)
34                 return ;
35             help(board, i-1, j, word, flag, num);
36             if(ans==1)
37                 return ;
38             help(board, i, j+1, word, flag, num);
39             if(ans==1)
40                 return ;
41             help(board, i, j-1, word, flag, num);
42             flag[i][j]=0;
43 
44         }
45         else
46             return ;
47 
48     }
49 
50     public static void main(String []args){
51         Solution3 s=new Solution3();
52         char [][] c={{'C','A','A'},{'A','A','A'},{'B','C','B'}};
53         String str="AAB";
54         System.out.println(s.exist(c,str));
55     }
56 }

 

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM