LeetCode 40
https://leetcode.cn/problems/combination-sum-ii/description/
难度:中等
高频面试题汇总:https://www.yuweihung.com/posts/2025/lc-hot/
为了避免得到重复的答案,首先对数组排序。如果选,递归到 i + 1,如果不选,跳过所有等于当前数的数,递归到 i + k。也就是对于相同的元素,只能按照顺序选,不能跳过一个选后面的。
时间复杂度:\(O(n\*2^2)\)
空间复杂度:O(n)
class Solution {
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
ranges::sort(candidates);
int n = candidates.size();
vector<vector<int>> ans;
vector<int> path;
auto dfs = [&](this auto&& dfs, int i, int left) -> void {
// 所选元素之和恰好等于 target
if (left == 0) {
ans.push_back(path);
return;
}
// 没有可以选的数字
if (i == n) {
return;
}
// 所选元素之和无法恰好等于 target
int x = candidates[i];
if (left < x) {
return;
}
// 选 x
path.push_back(x);
dfs(i + 1, left - x);
path.pop_back(); // 恢复现场
// 不选 x,那么后面所有等于 x 的数都不选
// 如果不跳过这些数,会导致「选 x 不选 x'」和「不选 x 选 x'」这两种情况都会加到 ans 中,这就重复了
i++;
while (i < n && candidates[i] == x) {
i++;
}
dfs(i, left);
};
dfs(0, target);
return ans;
}
};