zoukankan      html  css  js  c++  java
  • 77. 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],
    ]
    
    Hide Tags
     Backtracking 

    链接:  http://leetcode.com/problems/combinations/

    题解:

    求组合数。依然是使用recursive + backtracking,当所传list的大小等于k时,将list加入到result里。使用控制位置的变量pos根据题目要求从1开始,本体依然假定无重复数字。 

    Time Complexity - O(2n), Space Complexity - O(n)。                         --复杂度有点糊涂,还需要重新计算

    public class Solution {
        public ArrayList<ArrayList<Integer>> combine(int n, int k) {
            ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
            if(n < 0 || k < 0)
                return result;
            ArrayList<Integer> list = new ArrayList<Integer>();
            helper(result, list, n, k, 1);
            return result;
        }
        
        private void helper(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list, int n, int k, int pos){
            if(list.size() == k){
                result.add(new ArrayList<Integer>(list));
                return;
            }
            
            for(int i = pos; i <= n; i++){
                list.add(pos);
                helper(result, list, n, k, ++pos);
                list.remove(list.size() - 1);
            }
        }
    }

    Update:

    public class Solution {
        public List<List<Integer>> combine(int n, int k) {
            List<List<Integer>> res = new ArrayList<>();
            if(n < 0 || k < 0)
                return res;
            ArrayList<Integer> list = new ArrayList<Integer>();
            dfs(res, list, n, k, 1);
            return res;
        }
        
        private void dfs(List<List<Integer>> res, ArrayList<Integer> list, int n, int k, int position) {  // from 1 to n
            if(list.size() == k) {
                res.add(new ArrayList<Integer>(list));
                return;
            }
            
            for(int i = position; i <= n; i++) {
                list.add(i);
                dfs(res, list, n, k, i + 1);
                list.remove(list.size() - 1);
            }
        }
    }

    二刷

    有关这一类排列组合题目有不少题型,一定要好好思考总结融会贯通。

    依然是跟1刷类似的方法,使用DFS + Backtracking。要注意的是最后的结果是(1, 2), (1, 3), (1, 4), (2, 3), (2, 4)这类一定是升序的组合,所以我们构建辅助函数的时候只要pass in 一个position来控制就可以了。递归的时候传入 combine(res, list, k, n, i + 1)这样就能简单避免掉i,只丛i后面的数字继续遍历。

    这里branching factor是n, depth是k。 所以其实时间复杂度是 O(n! / k!) 约等于 O(n!)

    Time Complexity - O(n!), Space Complexity - O(nk)

    Java:

    public class Solution {
        public List<List<Integer>> combine(int n, int k) {
            List<List<Integer>> res = new ArrayList<>();
            List<Integer> list = new ArrayList<>();
            combine(res, list, n, k, 1);
            return res;
        }
        
        private void combine(List<List<Integer>> res, List<Integer> list, int n, int k, int pos) {
            if (list.size() == k) {
                res.add(new ArrayList<Integer>(list));
                return;
            }
            for (int i = pos; i <= n; i++) {
                list.add(i);
                combine(res, list, n, k, i + 1);
                list.remove(list.size() - 1);
            }
        }
    }

    三刷:

    方法跟二刷一样。也是构造递归求解的辅助方法来解决。注意这里我们也需要一个保存position的int pos。

    有机会要再算一算复杂度。 

    Java:

    public class Solution {
        public List<List<Integer>> combine(int n, int k) {
            List<List<Integer>> res = new ArrayList<>();
            if (n < 0 || k < 0 || n < k) return res;
            getCombinations(res, new ArrayList<Integer>(), n, k, 1);
            return res;
        }
        
        private void getCombinations(List<List<Integer>> res, List<Integer> list, int n, int k, int pos) {
            if (list.size() == k) {
                res.add(new ArrayList<>(list));
                return;
            }
            for (int i = pos; i <= n; i++) {
                list.add(i);
                getCombinations(res, list, n, k, i + 1);
                list.remove(list.size() - 1);
            }
        }
    }

    Reference:

    http://www.1point3acres.com/bbs/thread-117602-1-1.html

    http://codeganker.blogspot.com/2014/03/combinations-leetcode.html

    http://www.cnblogs.com/zhuli19901106/p/3485751.html

    http://www.1point3acres.com/bbs/thread-117602-1-1.html

    https://leetcode.com/discuss/42034/java-solution-easy-understood

    https://leetcode.com/discuss/30221/dfs-recursive-java-solution

    https://leetcode.com/discuss/61607/ac-python-backtracking-iterative-solution-60-ms

    https://leetcode.com/discuss/37021/1-liner-3-liner-4-liner

    https://leetcode.com/discuss/24600/iterative-java-solution

    https://leetcode.com/discuss/12915/my-shortest-c-solution-using-dfs

    https://leetcode.com/discuss/31250/backtracking-solution-java

    http://rangerway.com/way/algorithm-permutation-combination-subset/ 

    http://www.1point3acres.com/bbs/thread-117602-1-1.html

    http://www.cnblogs.com/zhuli19901106/p/3492515.html

  • 相关阅读:
    捷微商城小程序上线啦~
    JEECG 新版在线文档WIKI正式发布
    https 详解
    css 3 新特性
    js 基础(一)
    BFC
    .Net、C# 汉字转拼音,简体繁体转换方法
    丰富“WinForms” 的一个别样"项目"(学生管理)
    学生管理系统1
    学生管理系统
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4437119.html
Copyright © 2011-2022 走看看