From e601c0c729a0deab40982e672d02618bda76ff88 Mon Sep 17 00:00:00 2001 From: AronJudge <2286381138@qq.com> Date: Sun, 4 Sep 2022 10:39:02 +0800 Subject: [PATCH 1/2] =?UTF-8?q?0216.=E7=BB=84=E5=90=88=E6=80=BB=E5=92=8CII?= =?UTF-8?q?I?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加一种更简单的剪裁方式。 --- problems/0216.组合总和III.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/problems/0216.组合总和III.md b/problems/0216.组合总和III.md index 2c1bf717..50c0d746 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(); + } + } +} ``` 其他方法 From e1e22edf47fd7a975efaa814fd98327e865aa8ee Mon Sep 17 00:00:00 2001 From: AronJudge <2286381138@qq.com> Date: Sun, 4 Sep 2022 12:55:50 +0800 Subject: [PATCH 2/2] =?UTF-8?q?0040=20=E7=BB=84=E5=90=88=E6=80=BB=E5=92=8C?= =?UTF-8?q?II?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 简化原来的代码逻辑, 提高可读性。 --- problems/0040.组合总和II.md | 65 ++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/problems/0040.组合总和II.md b/problems/0040.组合总和II.md index 557eb855..efe14116 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