diff --git a/problems/0040.组合总和II.md b/problems/0040.组合总和II.md index 99577f0c..417f4a6d 100644 --- a/problems/0040.组合总和II.md +++ b/problems/0040.组合总和II.md @@ -258,40 +258,45 @@ public: **使用标记数组** ```Java class Solution { - List> lists = new ArrayList<>(); - Deque deque = new LinkedList<>(); - int sum = 0; + LinkedList path = new LinkedList<>(); + List> ans = new ArrayList<>(); + boolean[] used; + int sum = 0; - public List> combinationSum2(int[] candidates, int target) { - //为了将重复的数字都放到一起,所以先进行排序 - Arrays.sort(candidates); - //加标志数组,用来辅助判断同层节点是否已经遍历 - boolean[] flag = new boolean[candidates.length]; - backTracking(candidates, target, 0, flag); - return lists; - } + public List> combinationSum2(int[] candidates, int target) { + used = new boolean[candidates.length]; + // 加标志数组,用来辅助判断同层节点是否已经遍历 + Arrays.fill(used, false); + // 为了将重复的数字都放到一起,所以先进行排序 + Arrays.sort(candidates); + backTracking(candidates, target, 0); + return ans; + } - public void backTracking(int[] arr, int target, int index, boolean[] flag) { - if (sum == target) { - lists.add(new ArrayList(deque)); - return; - } - for (int i = index; i < arr.length && arr[i] + sum <= target; i++) { - //出现重复节点,同层的第一个节点已经被访问过,所以直接跳过 - if (i > 0 && arr[i] == arr[i - 1] && !flag[i - 1]) { - continue; - } - flag[i] = true; - sum += arr[i]; - deque.push(arr[i]); - //每个节点仅能选择一次,所以从下一位开始 - backTracking(arr, target, i + 1, flag); - int temp = deque.pop(); - flag[i] = false; - sum -= temp; - } + private void backTracking(int[] candidates, int target, int startIndex) { + if (sum == target) { + ans.add(new ArrayList(path)); } + for (int i = startIndex; i < candidates.length; i++) { + if (sum + candidates[i] > target) { + break; + } + // 出现重复节点,同层的第一个节点已经被访问过,所以直接跳过 + if (i > 0 && candidates[i] == candidates[i - 1] && !used[i - 1]) { + continue; + } + used[i] = true; + sum += candidates[i]; + path.add(candidates[i]); + // 每个节点仅能选择一次,所以从下一位开始 + backTracking(candidates, target, i + 1); + used[i] = false; + sum -= candidates[i]; + path.removeLast(); + } + } } + ``` **不使用标记数组** ```Java diff --git a/problems/0216.组合总和III.md b/problems/0216.组合总和III.md index 1ef278ff..964facee 100644 --- a/problems/0216.组合总和III.md +++ b/problems/0216.组合总和III.md @@ -260,6 +260,37 @@ class Solution { } } } + +// 上面剪枝 i <= 9 - (k - path.size()) + 1; 如果还是不清楚 +// 也可以改为 if (path.size() > k) return; 执行效率上是一样的 +class Solution { + LinkedList path = new LinkedList<>(); + List> ans = new ArrayList<>(); + public List> combinationSum3(int k, int n) { + build(k, n, 1, 0); + return ans; + } + + private void build(int k, int n, int startIndex, int sum) { + + if (sum > n) return; + + if (path.size() > k) return; + + if (sum == n && path.size() == k) { + ans.add(new ArrayList<>(path)); + return; + } + + for(int i = startIndex; i <= 9; i++) { + path.add(i); + sum += i; + build(k, n, i + 1, sum); + sum -= i; + path.removeLast(); + } + } +} ``` 其他方法