LeetCode(77):组合

Medium!php

题目描述:数组

给定两个整数 n 和 k,返回 1 ... 中全部可能的 k 个数的组合。markdown

示例:spa

输入: n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

解题思路:.net

这道题让求1到n共n个数字里k个数的组合数的全部状况,仍是要用深度优先搜索DFS来解,根据以往的经验,像这种要求出全部结果的集合,通常都是用DFS调用递归来解。那么咱们创建一个保存最终结果的大集合res,还要定义一个保存每个组合的小集合out,每次放一个数到out里,若是out里数个数到了k个,则把out保存到最终结果中,不然在下一层中继续调用递归。https://blog.csdn.net/u010500263/article/details/18435495中有一张图很好的说明了递归调用的顺序。code

C++解法一:blog

 1 class Solution {  2 public:  3     vector<vector<int>> combine(int n, int k) {  4         vector<vector<int>> res;  5         vector<int> out;  6         helper(n, k, 1, out, res);  7         return res;  8  }  9     void helper(int n, int k, int level, vector<int>& out, vector<vector<int>>& res) { 10         if (out.size() == k) res.push_back(out); 11         for (int i = level; i <= n; ++i) { 12             out.push_back(i); 13             helper(n, k, i + 1, out, res); 14             out.pop_back(); 15  } 16  } 17 };

对于n = 5, k = 3, 处理的结果以下:递归

1 2 3 
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5it

 

咱们再来看一种迭代的写法,也是一种比较巧妙的方法。这里每次先递增最右边的数字,存入结果res中,当右边的数字超过了n,则增长其左边的数字,而后将当前数组赋值为左边的数字,再逐个递增,直到最左边的数字也超过了n,中止循环。对于n=4, k=2时,遍历的顺序以下所示:io

0 0 #initialization 1 0 1 1 #push_back 1 2 #push_back 1 3 #push_back 1 4 #push_back 1 5 2 5 2 2 #push_back 2 3 #push_back 2 4 #push_back ... 3 4 #push_back 3 5 4 5 4 4 4 5 5 5 #stop 

C++解法二:

 1 class Solution {  2 public:  3     vector<vector<int>> combine(int n, int k) {  4         vector<vector<int>> res;  5         vector<int> out(k, 0);  6         int i = 0;  7         while (i >= 0) {  8             ++out[i];  9             if (out[i] > n) --i; 10             else if (i == k - 1) res.push_back(out); 11             else { 12                 ++i; 13                 out[i] = out[i - 1]; 14  } 15  } 16         return res; 17  } 18 };
相关文章
相关标签/搜索