本题大意:给定两个正整数n和k,求出从1到n中选择k个不同数字的所有可能情况,按照从小到大排列。例如:n=4,k=2,得到的结果为:
[ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
解题思路:该例很像小学数学中学常见的一种题,给定一个上面有4个点的线段,让你找出该线段上总共有多少线段。n和k变了以后,无非是要求经过的点要写出来,而经历少于k个结点的线段不能要了。我们可以在纸上模拟这个过程,然后用代码实现该过程就可以了。
具体做法:帮助函数combineHelper(vector<vector<int> >& result, vector<int>& tmp, int n, int k, int start),result和tmp的作用不用说了就是存储;n表示可选数据的范围;k表示可选数据的个数,当k为0时说明已经选数完毕,可以将tmp存入result了;每次选数(push)的时候,我们都给定一个范围,start就标示了可选的最小值。
注意:回溯,每次帮助函数返回以后都要将tmp末尾的元素删除,以便给新的元素留位置。
代码实现:
1 class Solution { 2 public: 3 vector<vector<int> > combine(int n, int k) { 4 vector<int> tmp; 5 vector<vector<int> > result; 6 combineHelper(result, tmp, n, k, 1); 7 return result; 8 } 9 void combineHelper(vector<vector<int> >& result, vector<int>& tmp, int n, int k, int start) 10 { 11 if(k == 0) 12 { 13 result.push_back(tmp); 14 return; 15 } 16 for(int i = start; i <= n; ++i) 17 { 18 19 tmp.push_back(i); 20 combineHelper(result, tmp, n, k-1, i+1); 21 tmp.pop_back(); 22 } 23 } 24 };