题目链接: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个整数n和k,返回1...n中所以k个数的组合。

由于要输出所以情况,因此可以考虑递归回溯输出所有情况。依次固定每一个数字作为开始,然后递归处理后面的数字即可。递归的时候逐层递减k,因此递归结束条件就是k等于1,此时需要记录该种情况。

其中b为生成组合的起始数字。

时间复杂度:O(???)(结果数量)

空间复杂度:O(???)(结果数量)

 1 class Solution
 2 {
 3 public:
 4     vector<vector<int> > combine(int n, int k)
 5     {
 6         vector<int> vi;
 7         combine(n, k, vi, 1);
 8         return vvi;
 9     }
10 private:
11     vector<vector<int> > vvi;
12     void combine(int n, int k, vector<int> &vi, int b)
13     {
14         if(k == 1)
15             vvi.push_back(vi);
16         else
17             for(int i = b; i <= n + 1 - k; ++ i)
18             {
19                 vi.push_back(i);
20                 combine(n, k - 1, vi, i + 1);
21                 vi.pop_back();
22             }
23     }
24 };

也可以事先按k的大小开出数组,这样可以减少push_back和pop_back的重复调用。

 1 class Solution
 2 {
 3 public:
 4     vector<vector<int> > combine(int n, int k)
 5     {
 6         vector<int> vi(k);
 7         combine(n, k, vi, 1);
 8         return vvi;
 9     }
10 private:
11     vector<vector<int> > vvi;
12     void combine(int n, int k, vector<int> &vi, int i)
13     {
14         while(i <= n)
15         {
16             vi[vi.size() - k] = i ++;
17             if(k == 1)
18                 vvi.push_back(vi);
19             else
20                 combine(n, k - 1, vi, i);
21         }
22     }
23 };