LeetCode:39 combination sum ;
阿新 • • 發佈:2018-12-04
一、
首先這個題和上一篇文章的遞歸回溯很像
求子集(上一篇文章的連結)
但是上一篇文章是求子集,但是還是不同的,舉一個例子
比如candidates=[2,3,6,7] target=7
上一篇求子集結果是什麼呢,結果中只有[7]是符合target的,但是我們這個題的結果是[7],[2,2,3]
因為求子集啊,子集裡面不包含同一個位置的相同元素(也就是不會出現[2,2],[2,2,2];但是如果集合是[2,2,6,7],子集會出現[2],[2][2,2],[2,6][2,6])
而我們這個題呢,求的是組合和,而且看例子,是可以有同一個位置的相同元素的組合的
那麼就可以這麼想,原先我們遞迴始終是從當前位置i的下一個位置i+1遞迴,那麼我們現在第一次遞迴可以從當前位置i繼續遞迴(也就是可以考慮當前元素);然後問題來了,第二次遞迴,也就是一直到第一次的遞迴方式走到頭了,執行i+1的第二個遞迴
下面這個圖是別人部落格裡[2,3,5]的例子,可以參考看一下
(1)我的java程式碼(可以說,我沒有見過網上有我這種使用兩個遞迴的方法,我猜。我挺喜歡左程雲老師的程式碼風格的,遞迴題就全部用遞迴,不巢狀迴圈)
class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { List <Integer> result=new ArrayList<Integer>(); List<List<Integer>> results =new ArrayList<List<Integer>>(); if(candidates==null||candidates.length==0) return results; //傳入的引數,陣列,二維list,每一行的List,sum和,目標和target Arrays.sort(candidates); process(candidates,0,results,result,0,target); return results; } public static void process (int[]candidates,int i,List<List<Integer>>results,List<Integer>result,int sum,int target){ if(i>candidates.length-1||sum>target) return; if(target==sum){ results.add(new ArrayList<Integer>(result)); return; } sum+=candidates[i]; result.add(candidates[i]); process(candidates,i,results,result,sum,target); result.remove(result.size()-1); sum-=candidates[i]; process(candidates,i+1,results,result,sum,target); } }
(2)網上大部分人的做法
public class Solution { List<List<Integer>> result; List<Integer> solu; public List<List<Integer>> combinationSum(int[] candidates, int target) { result = new ArrayList<>(); solu = new ArrayList<>(); Arrays.sort(candidates); getCombination(candidates, target, 0, 0); return result; } public void getCombination(int[] candidates, int target, int sum, int level){ if(sum>target) return; if(sum==target){ result.add(new ArrayList<>(solu)); return; } for(int i=level;i<candidates.length;i++){ sum+=candidates[i]; solu.add(candidates[i]); getCombination(candidates, target, sum, i); solu.remove(solu.size()-1); sum-=candidates[i]; } } }