組合總和
阿新 • • 發佈:2018-12-06
給定一個無重複元素的陣列 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]
]
方法:遞迴
思路:
1,首先對陣列進行排序,方便操作並且節省開支;
2,陣列[2,3,6,7],target = 7,定義一個存放臨時結果的list,每次需要從start元素開始,比如,先將2存入list,然後target就變成7-2=5,再將2放入list,target就變成5-2=3,再將2放入list,target就是3-2=1,然後再拿start位置元素還是2,但是2比1大,所以不行,那麼就將list最後一個元素2去掉,然後將下一個元素也就是3存入list,這時候target變成了0,滿足條件,將這個list存入結果集res裡面;
3,按照第二步所描述的過程,遞迴迭代這個陣列,將符合條件的元素組合全部拿到即可!
class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { Arrays.sort(candidates); List<Integer> list = new ArrayList<>();//新建堆疊用來判斷 List<List<Integer>> res = new ArrayList<>();//結果集 if (candidates == null || candidates.length == 0) return res; combin(candidates, 0, target, list, res); return res; } //對陣列元素(已排序)進行逐個判斷以及加入結果集 private void combin(int[] candidates, int start, int target,List<Integer> list, List<List<Integer>> res) { //剛好滿足則將結果存入結果集 if (target == 0) { res.add(new ArrayList<>(list)); return; } for (int i = start; i < candidates.length; i ++) { if (candidates[i] <= target) { //判斷是否已經大於target list.add(candidates[i]);//將第一個元素存入 combin(candidates, i, target -candidates[i] , list, res);//繼續判斷進棧元素 list.remove(list.size() - 1);//不滿足則將最後一個元素移除,進棧新元素判斷 } } } }
注意:對陣列先排序,然後可以判斷如果當前元素已經超出,那麼後續肯定全部超出,不必浪費時間,可以提升效率!