题目链接:
https://leetcode-cn.com/problems/combination-sum-iii/
难度:中等
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]]
勉强做出来了 ,写的有些垃圾,中间还走了错路(代码垃圾 记录下来 做个提醒)
for 循环 一开始是我没想到的,不使用的话最终结果会有重复。(这不就是昨天题目的思路吗。。 不过昨天状态不好)
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combinationSum3(int k, int n) {
vector<int> tmp;
dfs(k,1,n,tmp);
return res;
}
void dfs(int k,int pos,int rest,vector<int> &tmp){
int num=tmp.size();
if(num==k||rest<=0){
if(num==k&&!rest){
res.push_back(tmp);
}
return;
}
for(int i=pos;i<=9;i++){
tmp.push_back(i);
dfs(k,i+1,rest-i,tmp);
tmp.pop_back();
}
}
};
剩下的思路是题解的 (第一个方法感觉不太好)
这个是将所有的情况全部考虑的一遍 注意:所有 二的九次方 所有情况全部判断一下
class Solution {
public:
vector<vector<int>> res;
vector<int> temp;
vector<vector<int>> combinationSum3(int k, int n) {
// i<(1<<9=512) 0-511 共512种情况 对应的二进制位
// 1代表选择 0代表不选
// (1<<i)&mash 判断哪个位置是1
// 在push的时候要(i+1) (对应数字是1-9 而位置是0-8)
// 当然这种情况肯定是不会有冲突的
for(int i=0;i<(1<<9);++i){
if(check(i,k,n)){
res.push_back(temp);
}
}
return res;
}
bool check(int mash,int k,int n){
temp.clear();
for(int i=0;i<9;++i){
if((1<<i)&mash){
temp.push_back(i+1);
}
}
// 保证共有k个
// accumulate第一次看见 求和的
return temp.size()==k&&accumulate(temp.begin(),temp.end(),0)==n;
}
};
还有种比较好的方法 看起来比较美观
class Solution {
public:
vector<vector<int>> res;
vector<int> temp;
vector<vector<int>> combinationSum3(int k, int n) {
dfs(1,9,k,n);
return res;
}
// cur当前的数值
// n=9 没有也没事 直接把n改成9也行。。。
// k 记录需要几个数字
// sum相当于combinationSum3(k,n) 中的n 需要的和
void dfs(int cur,int n,int k,int sum){
// 到不了k个 或者 超过k个 结束
if (temp.size()+(n-cur+1)<k||temp.size()>k) {
return;
}
if(temp.size()==k&&accumulate(temp.begin(),temp.end(),0)==sum){
res.push_back(temp);
return;
}
temp.push_back(cur);
dfs(cur+1,n,k,sum);
temp.pop_back();
dfs(cur+1,n,k,sum);
}
};