LeeCode 39 組合總和(天坑啊java的值傳遞,頭都被打懵了)
阿新 • • 發佈:2018-12-11
給定一個無重複元素的陣列 candidates
和一個目標數 target
,找出 candidates
中所有可以使數字和為 target
的組合。
candidates
中的數字可以無限制重複被選取。
說明:
- 所有數字(包括
target
)都是正整數。 - 解集不能包含重複的組合。
示例 1:
輸入: candidates =[2,3,6,7],
target =7
, 所求解集為: [ [7], [2,2,3] ]
示例 2:
輸入: candidates = [2,3,5],
target = 8,
所求解集為:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
啊,此題真是,一言難盡啊,先上報錯程式碼(因為一直找不到錯誤,還以為邏輯錯了,就把C/C++的正確程式碼重寫了一遍,沒想到還是一直報錯,最後靈機一動,想到值傳遞這件事,才AC程式碼):
package LeetCode; import java.util.*; public class Lee_39_SumOfZuHe { public static void main(String[] args){ int[] candidates = new int[]{2,3,6,7}; int target = 7; new Lee_39_SumOfZuHe().combinationSum(candidates,target); } public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> list = new ArrayList<List<Integer>>(); List<Integer> mylist = new ArrayList<Integer>();; Arrays.sort(candidates); //System.out.println(Arrays.toString(candidates)); ReccombinationSum(candidates,target,0,mylist,list); //System.out.print(list); return list; } public void ReccombinationSum(int[] Newcandidates,int sum,int start,List<Integer> mylist,List<List<Integer>> list){ if(sum<0) return; else if(sum==0){ list.add(mylist); return; } else{ for(int i=start;i<Newcandidates.length;i++){ int current = Newcandidates[i]; mylist.add((Integer)current); ReccombinationSum(Newcandidates,sum-current,i,mylist,list); //主要是此行程式碼 mylist.remove((Integer)current); } } } }
結果跑出了空結果:
加了一行檢測程式碼,發現能跑出正確結果,說明只是list沒能真正新增元素:
那麼問題出在哪呢?難受啊兄die~~~
後面理解了值傳遞,改了程式碼:
ReccombinationSum(Newcandidates,sum-current,i,mylist,list);
ReccombinationSum(Newcandidates,sum-current,i,new ArrayList<Integer>(mylist),list);
可以看見,主要是在遞迴過程中重新建立了物件,其實理解了java的值傳遞模式就能理解了,當mylist作為形參進行傳遞時,傳遞的是mylist的地址值,當然可以通過對mylist的地址值對物件進行操作,然而如果不重新new一個mylist出來,在進行list.add(mylist)的時候,只會把這一個物件進行add,然而再往後遞迴的時候,由於mylist是一個物件,mylist先add後remove自然會將mylist清空,而list真正add的其實是mylist的地址,add了兩次其實是add了mylist這一個物件兩次,然後mylist又被清空,所以結果只能是[ [ ] , [ ] ],更改程式碼後,結果AC~~~
話說回來,博主之前也做過類似的遞迴題,不過由於用的不是list這樣通過地址值傳遞的遞迴,而是利用String 進行遞迴,沒出現問題,現在想來,String作為不可變數,每次更改時其實都是重新申請了String物件,暗合值傳遞理念,只能說博主還是太年輕啊~~引以為鑑!