Combinations
题目:Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
For example,
If n = 4 and k = 2, a solution is:
[ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
思路:回溯法+动态规划
更加推荐第一种解法。第二种实在没有能够理解。以后的回溯法尽量使用本模型。
我将本答案的解法过程一一列举,应该能够容易理解。
进入第二个循环的时候,先是进入2,进入第三个循环,发现满了,保存,返回,退出,继续进入3,以此类推。
1,2,– 1,3 — 1,4 — …
第二种方法是:用answer中的长度作为结束条件,还有一个条件就是写入的值不能大于n,这个是第二条件了。
不过在最后,要加上combineHelper(n,k,start+1,answer,result);不然只是求解了一个插入首字母的结果。
不过,这不是最完美的回溯法的典型程序,可以参考我之后的求解和的程序。
代码:
class Solution1 {
public:
void combineHelper(int n,int k,int start,vector<int> &answer,vector<vector<int> >&result){
if(answer.size()==k){
result.push_back(answer);
return;
} //answer暂时保存k位数字
if(answer.size()>k){//节省不必要浪费时间
return;
}
for(int i=start;i<=n;i++){
answer.push_back(i);
combineHelper(n,k,i+1,answer,result);
answer.pop_back();
}
//虽然这边写的是删除一个值,但是因为是迭代,所以第一个函数运行到这边的时候,
//实际相当于把第一次的一整个vector清空,验证这个可以通过把下面的那个语句屏蔽到
//发现只能生成一组vector。
//这个程序谨记,第一次遇到。
//所以下面的值为start+1,而不是start+2.
}
vector<vector<int> > combine(int n, int k) {
vector<vector<int> >result;
vector<int>answer;
combineHelper(n,k,1,answer,result);
return result;
}
};class Solution2 {
public:
void combineHelper(int n,int k,int start,vector<int> &answer,vector<vector<int> >&result){
if(answer.size()==k){
result.push_back(answer);
return;
} //answer暂时保存k位数字
if(start>n){
return;
}
answer.push_back(start);
combineHelper(n,k,start+1,answer,result);
answer.pop_back();
//虽然这边写的是删除一个值,但是因为是迭代,所以第一个函数运行到这边的时候,
//实际相当于把第一次的一整个vector清空,验证这个可以通过把下面的那个语句屏蔽到
//发现只能生成一组vector。
//这个程序谨记,第一次遇到。
//所以下面的值为start+1,而不是start+2.
combineHelper(n,k,start+1,answer,result);
}
vector<vector<int> > combine(int n, int k) {
vector<vector<int> >result;
vector<int>answer;
combineHelper(n,k,1,answer,result);
return result;
}
};

浙公网安备 33010602011771号