[ 回溯 ]组合总和II

40. 组合总和 II - 力扣(LeetCode) (leetcode-cn.com)

组合总和II

  • DFS
  • 回溯
  • 去重
class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;

    void DFS(vector<int>& candidates, int target, int sum, int index, vector<bool>& visited) {
        if (sum > target) return;
        if (sum == target) {
            ans.emplace_back(path);
            return;
        }
        for (int i = index; i < candidates.size(); ++i) {
            // 产生重复的原因在于产生了相同的结果组,而不是某个数选了很多次
            // 假设候选组为[1,2,1,5,1], 要产生和为9的组
            // 那么有[1,2,1,5]和[1,2,5,1]以及[2,1,5,1]这3组答案产生
            // 1,2组, 在第一个for循环时,选了两次1
            // 1,3组, 在第二个for循环时,选了之前选过的1。
            // 去重方法,先排序相邻方便比较去重
            // 然后再用访问数组表示是否在同一层中,防止类似[1,1]这样不同层的相同数字会被if条件直接舍去
            if (i > 0 && candidates[i] == candidates[i - 1] && visited[i - 1] == false) continue;

            sum += candidates[i];
            path.emplace_back(candidates[i]);
            visited[i] = true;
            DFS(candidates, target, sum, i+1, visited);
            visited[i] = false;
            sum -= candidates[i];
            path.pop_back();
        }
    }

    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<bool> visited(candidates.size(), false);
        sort(candidates.begin(), candidates.end());
        DFS(candidates, target, 0, 0, visited);
        return ans;
    }
};

上一篇:LeetCode-040-组合总和 II


下一篇:2021-04-17