diff --git a/README.md b/README.md index 0a53dee..b7e6144 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,7 @@ * [q10_正则表达式匹配](/src/回溯法/q10_正则表达式匹配) * [q22_括号生成](/src/回溯法/q22_括号生成) +* [q40_组合总和2](/src/回溯法/q40_组合总和2) * [q46_全排列](/src/回溯法/q46_全排列) ### 树的遍历 diff --git a/src/回溯法/q40_组合总和2/Solution.java b/src/回溯法/q40_组合总和2/Solution.java new file mode 100644 index 0000000..4faf116 --- /dev/null +++ b/src/回溯法/q40_组合总和2/Solution.java @@ -0,0 +1,38 @@ +package 回溯法.q40_组合总和2; + +import java.util.*; + +/** + * 回溯法 O(n*log(n)) + */ +class Solution { + + public List> combinationSum2(int[] candidates, int target) { + List> res = new ArrayList<>(); + if (candidates.length == 0) { + return res; + } + Arrays.sort(candidates); + helper(candidates, target, 0, new LinkedList<>(), res); + return res; + } + + public void helper(int[] candidates, int target, int start, LinkedList stack, List> res) { + if (start > candidates.length) { + return; + } + if (target == 0 && !stack.isEmpty()) { + List item = new ArrayList<>(stack); + res.add(item); + } + HashSet set = new HashSet<>(); + for (int i = start; i < candidates.length; ++i) { + if (!set.contains(candidates[i]) && target >= candidates[i]) { + stack.push(candidates[i]); + helper(candidates, target - candidates[i], i + 1, stack, res); + stack.pop(); + set.add(candidates[i]); + } + } + } +}