leetcode 40.组合总和 去重

116 阅读1分钟

39. 组合总和 - 力扣(LeetCode) 如下图,这个递归图我们这样画:

image.png

这道题最重要的一点就是可以重复值

比如当第一次取2的时候,下一层仍然是【2,3,6,7】而不是【3,6,7】,这样才能保证它可以有【2,2,3】这个结果。

如果放在代码里面是怎么实现的呢?

我们在递归的时候传i而不传i+1就不会让第二次调用的时候越过2直接取3了。

temp==target时停止递归

黄色部分为减枝操作,即temp>target就没必要再往下走了,就返回。

Code:

class Solution {
public:
vector<int>temp;
vector<vector<int>>result;
int sum=0;
void backtracking(int startindex,vector<int>& candidates, int target)
{
  
    
    if(sum>target)return;
    //递归结束条件
    if(sum==target)
    {
        result.push_back(temp);
    }


    //单层逻辑
    for(int i=startindex;i<candidates.size();i++)
    {
        temp.push_back(candidates[i]);
        sum+=candidates[i];

        backtracking(i,candidates,target);//不是i+1   i表示可以重复
        temp.pop_back();
        sum-=candidates[i];

    }

}


    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        backtracking(0,candidates,target);
        return result;
    }
};


OK,我们接着再来写这道题

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

这道题首先是无序的,我们可以让它先变有序。

注意

这道题和上面的 39. 组合总和 - 力扣(LeetCode)只有两个地方不同:

image.png

我们把39. 组合总和 - 力扣(LeetCode)的题解拿来跑一下:

image.png

发现我们的输出会有几个重复的组合。 重复的原因如下:

同一树层的重复取值:

image.png 我们应该做一个去重判断。 如果同一树层的前一个节点取过了值了,后面的节点就不能再取这个值。

回溯算法中的去重,树层去重树枝去重,你弄清楚了没?| LeetCode:40.组合总和II_哔哩哔哩_bilibili