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();
}
}
};
*/