[ 回溯 ]组合总和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;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回溯法求解组合总和的主要思路是:对于每个数字,可以选择使用或不使用,如果使用了,则将其加入当前组合中,并继续考虑剩下的数字;如果不使用,则直接考虑剩下的数字。当目标值减为0时,说明已经找到了一个符合要求的组合。 以下是一个求解组合总和的JavaScript代码示例: ```javascript function combinationSum(candidates, target) { const res = []; candidates.sort((a, b) => a - b); // 排序 backtrack([], 0, target); return res; function backtrack(path, start, target) { if (target < 0) return; // 如果目标值小于0,说明不符合要求,结束当前回溯 if (target === 0) { // 如果目标值等于0,说明已经找到了一个符合要求的组合 res.push([...path]); return; } for (let i = start; i < candidates.length; i++) { path.push(candidates[i]); // 将当前数字加入组合中 backtrack(path, i, target - candidates[i]); // 继续考虑剩下的数字 path.pop(); // 回溯,将当前数字从组合中移除 } } } ``` 在代码中,backtrack函数用于进行回溯。它接受三个参数:当前组合path、起始数字的下标start和目标值target。在函数中,遍历候选数字数组,对于每个数字,有两种选择:使用或不使用。如果使用,将其加入当前组合path,继续考虑剩下的数字;如果不使用,直接考虑剩下的数字。当目标值减为0时,说明已经找到了一个符合要求的组合,将其加入结果数组res中,并退出当前回溯
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值