【Leetcode】77. Combinations

题目地址:

https://leetcode.com/problems/combinations/

n n n个数字里取 k k k个的全部组合。经典的回溯法。代码如下:

import java.util.ArrayList;
import java.util.List;

public class Solution {    
    public List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> res = new ArrayList<>();
        dfs(n, 1, k, new ArrayList<>(), res);
        return res;
    }
    // pos为开始选择的数,cur为当前已经加入的数
    private void dfs(int n, int pos, int k, List<Integer> cur, List<List<Integer>> res) {
    	// 如果当前已经加入了k个数,则加入最后的res
        if (cur.size() == k) {
            res.add(new ArrayList<>(cur));
            return;
        }
        
    	// 从pos开始枚举,如果从pos到n之间还有足够个数加进cur中,就进行循环
        for (int i = pos; i <= n - (k - cur.size()) + 1; i++) {
        	// 枚举当前数
            cur.add(i);
            // 枚举下一个数
            dfs(n, i + 1, k, cur, res);
            // 枚举完要恢复现场
            cur.remove(cur.size() - 1);
        }
    }
}

时间复杂度 O ( k ( n k ) ) = O ( n ( n − 1 k − 1 ) ) O(k{n \choose k})=O(n{{n-1}\choose {k-1}}) O(k(kn))=O(n(k1n1)),先产生组合数,再加入res;空间复杂度 O ( k ) O(k) O(k),递归栈深度以及cur长度。

注解:k - cur.size()表示cur里还可以加多少个数。而 [ n − ( k − c u r . s i z e ( ) ) + 1 , n ] [n - (k - cur.size()) + 1, n] [n(kcur.size())+1,n]中元素个数恰好就是k - cur.size(),所以 i i i只需要搜到 n − ( k − c u r . s i z e ( ) ) + 1 n - (k - cur.size()) + 1 n(kcur.size())+1就可以了。

你可能感兴趣的:(#,DFS,BFS与图论)