深度递归,时间复杂度O(n!),空间O(n)。
class Solution {
public:
vector<vector<int> > combine(int n, int k) {
vector<vector<int> > result;
vector<int> path;
dfs(n, k, 1, path, result);
return result;
}
void dfs(int n, int k, int start, vector<int> &path, vector<vector<int> > &result)
{
if(path.size() == k)
{
result.push_back(path);
return;
}
for(int i=start; i<=n; ++i)
{
path.push_back(i);
dfs(n, k, i+1, path, result);
path.pop_back();
}
}
};
Method 2. compute combination using next_permutation.
first create an boolean array of size n, with the last k elements inited with true and other elements false. Then for each permutation of the array, we push the corresponding combination to the result. Great idea !
Code:
class Solution {
public:
vector<vector<int> > combine(int n, int k) {
vector<vector<int> > result;
vector<int> path;
vector<bool> selected(n, false);
for(int i=0; i<k; i++)
selected[n-i-1] = true;
do {
path.clear();
for(int i=0; i<n; i++)
{
if(selected[i])
path.push_back(i+1);
}
result.push_back(path);
}
while(next_permutation(selected));
return result;
}
bool next_permutation(vector<bool> &selected)
{
const int n = selected.size();
int i = n-1, k = n-1;
for(; i>0; i--)
{
if(selected[i] && !selected[i-1])
break;
}
if(i == 0) return false;
for(; k>=i; k--)
if(selected[k]) break;
bool tmp = selected[i-1];
selected[i-1] = selected[k];
selected[k] = tmp;
reverse(selected.begin()+i, selected.end());
return true;
}
};