40. Combination Sum II Medium

本文介绍了一种解决组合求和问题的算法实现,针对数组包含重复数字的情况进行了特别处理。通过对数组进行排序并使用回溯法,确保了结果集中没有重复的组合,并通过标记已访问过的元素避免了重复选取相同数值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一题的加强版,主要思路类似,建议与上一题同时食用。。。这题题目的变化是,数组不再有序,同时有了重复的数字出现,但不允许多次取同一个值,这就稍微有点麻烦。二话不说先排序,方便后续操作。

这里需要满足的要求有两个:首先,每一次迭代,在遍历候选元素的时候,同一位置的元素如果上一次迭代已经选过,这次不能选。其次,每一次迭代,相同元素,只能选择一个继续迭代,否则会有重复结果产生,例如数组中有连续3个2出现,你只能选择一个2迭代,然后继续遍历2后边的元素。

想清楚这一点就好办了,为了解决上述第一个要求,我们用一个bool数组,来记录每个位置是否被访问,如果被访问过,则这次迭代不再选择。为了解决第二个要求,我们在一次选择和处理后,用一句:while(i + 1 < candidates.size() && candidates[i + 1] == candidates[i])i++;(这是上次有道题目里,答案用了这个方式来跳过数组中后续的相同元素,忘了是哪道),这样就达到了不重复迭代的要求。

class Solution {
public:
	vector<vector<int> > results;
    vector<vector<int> > combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(), candidates.end());
        results.clear();
        vector<int> cur;
        bool visit[candidates.size()] = {0};
        backtracking(candidates, target, cur, visit);
        return results;
    }
    void backtracking(vector<int>& candidates, int target, vector<int>& cur, bool * visit)
    {
    	int prePick = cur.empty()? 0: cur[cur.size() - 1];
    	for(int i = 0; i < candidates.size(); i++){

    		if(candidates[i] >= prePick && candidates[i] <= target){
    			if(!visit[i]){
    				visit[i] = 1;
    				cur.push_back(candidates[i]);
    				if(candidates[i] == target) results.push_back(cur);
    				else backtracking(candidates, target - candidates[i], cur, visit);
    		    	cur.pop_back();
    		    	visit[i] = 0;

    		    	while(i + 1 < candidates.size() && candidates[i + 1] == candidates[i])i++;
    			}
    		}
    	}
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值