1. 题意
找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
2. 题解
2.1 回溯
cpp
class Solution {
public:
void search(int begin, vector<vector<int>> &ans,vector<int> &seq, int sum,
int n,int k) {
if ( sum == n && seq.size() == k) {
ans.emplace_back( seq );
return;
}
if ( sum > n || seq.size() > k)
return;
for (int i = begin; i < 10; i++) {
seq.emplace_back(i);
search( i + 1,ans, seq, sum + i, n, k);
seq.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
int mx = (9 + (10 - k)) * k / 2;
vector<vector<int>> ans;
if ( mx < n)
return ans;
vector<int> seq;
search(1, ans, seq, 0, n, k);
return ans;
}
};
2.2 二进制枚举
直接枚举每一种可能,判断是否满足即可。
cpp
class Solution {
public:
bool check(int v, int n, int k) {
int one_cnt = 0;
int sum = 0;
for (int i = 0;i < 9; ++i) {
if (v & (1 << i))
one_cnt++, sum += i + 1;
}
return one_cnt == k && sum == n;
}
vector<vector<int>> combinationSum3(int k, int n) {
vector<vector<int>> ans;
vector<int> seq;
for (int i = 1; i < (1 << 9); ++i) {
if ( check(i, n, k) ) {
seq.clear();
for (int j = 0;j < 9; ++j) {
if ( i & (1 << j))
seq.emplace_back( j + 1);
}
ans.emplace_back(seq);
}
}
return ans;
}
};