zoukankan      html  css  js  c++  java
  • LeetCode(77):组合

    Medium!

    题目描述:

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

    示例:

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

    解题思路:

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

    C++解法一:

     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 5

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

    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 };
  • 相关阅读:
    C++ 用宏实现swap(a,b)
    C++ string类的实现
    博客园代码高亮Html转换小程序,Linux/Mac下可用
    C++STL
    数据结构课程设计(基于二叉排序树的身份证管理系统)
    简单模拟B1011
    简单模拟B1001
    双向链表的双向冒泡排序 c++
    IO流处理文件读取到字节数组,再从字节数组读取到文件,Java实现
    Java多人聊天室第一版
  • 原文地址:https://www.cnblogs.com/ariel-dreamland/p/9154419.html
Copyright © 2011-2022 走看看