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],
]

一刷
题解:经典的backtracking
这里branching factor是n, depth是k。 所以其实时间复杂度是 O(n! / k!) 约等于 O(n!)
Time Complexity - O(2^n), Space Complexity - O(n)。

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

注意,曾经将递归表达式写作 combine(res, n, k, pos+1, list);
会得到完全不一样的结果,比如会出现[[1,2],[1,3],[2,2],[2,3],[3,2],[3,3]], 原因是,如果不自加,当1出栈后,pos还是1,i为2,也就是当压入2后,调用 combine(res, n, k, 2, list); 而不是combine(res, n, k, 3, list)。会引入[2,2]这种结果,所以pos需要自加。因为pos决定递归后加入的数值范围,所以也可以写为:

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

二刷

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

你可能感兴趣的:(77. Combinations)