leetcode 216.组合总和III

leetcode 216.组合总和III

题干

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
说明
所有数字都是正整数。
解集不能包含重复的组合。

示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]

示例 2:
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]

题解

leetcode官方题解
* 利用二进制数保存了2^9种情况,这道题数据量不大所以可用
* 遍历从1到1<<9的所有情况,假如数字符合要求就推入vector

class Solution {
    
    
public:
    vector<vector<int>> ans;
    vector<int> temp;
    bool check(int mask,int k,int n){
    
    
        temp.clear();
        for(int i=0;i<9;i++)
        {
    
    
            if(((1<<i)&mask)>0)//检查mask第i位,若第i位为1则判断大于0则数字i+1推入temp中
            {
    
    
                temp.push_back(i+1);
            }
        }//return处需要检查temp中数字个数是否为k且和是否为n
        return temp.size()==k&&accumulate(temp.begin(),temp.end(),0)==n;

    }

    vector<vector<int>> combinationSum3(int k, int n) {
    
    
        for(int mask=1;mask<(1<<9);mask++)
        {
    
    
            if(check(mask,k,n))
            {
    
    
                ans.push_back(temp);
            }
        }
        return ans;
    }
};

理论正确的dfs剪枝,不知道哪里出了问题结果总为空
* 不要在函数参数里重新定义全局变量啊啊啊啊啊啊

class Solution {
    
    
public:
    vector<vector<int>> ans;
    vector<int> temp;
    void dfs(vector<vector<int>> ans,vector<int> tempAns,int k,int n,int lastChoice){
    
    
        if((accumulate(tempAns.begin(),tempAns.end(),0)==n)&&(tempAns.size()==k))
        {
    
    
            ans.push_back(tempAns);
            
            auto t = ans.back();
            for(auto i=t.begin();i<t.end();i++)
                cout<<*i<<' ';
            cout<<endl;

            return;
        }
        if(accumulate(tempAns.begin(),tempAns.end(),0)>n||tempAns.size()>k)
            return;
        for(int i=lastChoice+1;i<=9;i++)
        {
    
    
            tempAns.push_back(i);
            dfs(ans,tempAns,k,n,i);
            tempAns.pop_back();
        }
    }
    vector<vector<int>> combinationSum3(int k, int n) {
    
    
        dfs(ans,temp,k,n,0);
        return ans;
    }
};

正确版

class Solution {
    
    
public:
    vector<vector<int>> ans;
    vector<int> temp;
    void dfs(vector<int> tempAns,int k,int n,int lastChoice){
    
    
        if((accumulate(tempAns.begin(),tempAns.end(),0)==n)&&(tempAns.size()==k))
        {
    
    
            ans.push_back(tempAns);
            return;
        }
        if(accumulate(tempAns.begin(),tempAns.end(),0)>n||tempAns.size()>k)
            return;
        for(int i=lastChoice+1;i<=9;i++)
        {
    
    
            tempAns.push_back(i);
            dfs(tempAns,k,n,i);
            tempAns.pop_back();
        }
    }
    vector<vector<int>> combinationSum3(int k, int n) {
    
    
        dfs(temp,k,n,0);
        return ans;
    }
};

可以通过加&的参数传入来避免函数内部反复开辟节省内存,比如下面这种写法(虽然不是这题)

class Solution {
    
    
public:
    vector<vector<int>> ans;
    void dfs(vector<int> &tempAns,int k,int n,int lastChoice,int move){
    
    
        if(move==k)
        {
    
    
            ans.push_back(tempAns);
            return;
        }
        else if(move>k)
            return;
            
        for(int i=lastChoice+1;i<=n;i++)
        {
    
    
            tempAns.push_back(i);
            dfs(tempAns,k,n,i,move+1);
            tempAns.pop_back();
        }
    }
    vector<vector<int>> combine(int n, int k) {
    
    
        
        vector<int> temp;
        dfs(temp,k,n,0,0);
        return ans;
    }
};


/*
class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        vector<vector<int>> ans;
        vector<int> path;
        helper(1, n , k, path, ans);
        return ans;
    }
    void helper(int startNum, int n, int k, vector<int> &path, vector<vector<int>> &ans) {
        if (k == 0) {
            ans.emplace_back(path);
            return;
        }
        for(int i = startNum; i <= n - k + 1; i++) {
            path.emplace_back(i);
            helper(i + 1, n, k - 1, path, ans);
            path.pop_back();
        }
    }
};
*/

猜你喜欢

转载自blog.csdn.net/weixin_43662405/article/details/108674113