leetcode 39. Combination Sum-回溯演算法|遞迴|非遞迴
阿新 • • 發佈:2019-01-08
【思路-Java】 回溯演算法|遞迴實現
本題採用回溯演算法。
1. 基本思路是先排好序,這樣做的目的是為了對陣列後面不可能出現的情況進行排除,有利於減少查詢時間,即剪枝操作
2. 外層迴圈對陣列元素依次進行遍歷,依次將 nums 中的元素加入中間集,一旦滿足條件,就將中間集加入結果集
3. 然後每次遞迴中把剩下的元素一一加到結果集合中,並且把目標減去加入的元素,然後把剩下元素(包括當前加入的元素)放到下一層遞迴中解決子問題。
演算法複雜度因為是NP問題,所以自然是指數量級的:
168 / 168 test cases passed. Runtime: 5 ms Your runtime beats 76.66% of javasubmissions.public class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { Arrays.sort(candidates); List<List<Integer>> res = new ArrayList<>(); List<Integer> temp = new ArrayList<>(); dfs(res, temp, target, candidates, 0); return res; } private void dfs(List<List<Integer>> res, List<Integer> temp, int target, int[] candidates, int j) { if(target == 0) { //滿足條件,將中間集加入結果集 res.add(new ArrayList<>(temp)); } for(int i = j; i < candidates.length && target >= candidates[i]; i++) { //target>=candidates[i]是剪枝操作 temp.add(candidates[i]); dfs(res, temp, target - candidates[i], candidates, i); temp.remove(temp.size() - 1); } } }
【思路2-Python】回溯演算法|非遞迴實現
提供非遞迴實現程式碼168 / 168 test cases passed. Runtime: 96 ms Your runtime beats 92.59% of pythonsubmissions.class Solution(object): def combinationSum(self, candidates, target): """ :type candidates: List[int] :type target: int :rtype: List[List[int]] """ candidates, res, stack, lenth=sorted(set(candidates)), [], [(0, [], target)], len(candidates) while stack: i, temp, tar=stack.pop() while i<lenth and tar>0: if candidates[i]==tar: res+=temp+[candidates[i]], stack+=(i, temp+[candidates[i]], tar-candidates[i]), i+=1 return res