216. Combination Sum III

题目:

Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.

Ensure that numbers within the set are sorted in ascending order.


Example 1:

Input: k = 3, n = 7

Output:

 

[[1,2,4]]

 


Example 2:

Input: k = 3, n = 9

Output:

 

[[1,2,6], [1,3,5], [2,3,4]]

链接: http://leetcode.com/problems/combination-sum-iii/

题解: 

Combination Sum 3,求和为n的k位组合数,输入number只有{1, 2, 3, 4, 5, 6, 7, 8, 9}并且无重复。 首先的想法是dfs + backtracking,不用花很多时间就可以写出来。

Time Complexity - O(29),  Space Complexity - O(n) 

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

 

还看到一个很好的写法,因为输入只有1 ~ 9,结果也只是1 ~ 9里k个数的组合那么我们可以暴力遍历所有的29个数。这里有个比较巧妙的地方就是我们只用找有k个1 bit的数字,然后再计算是否满足条件和为n。(原理我也没想明白,数学不好...)

这样下来Time Complexity 依然是O(29), Space Complexity - O(n), 不过可以节省掉递归栈的开销。

 

二刷:

方法跟一刷基本一样。

Java:

Time Complexity - O(29),  Space Complexity - O(n) 

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

 

三刷:

Java:

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

 

 

Reference:

https://leetcode.com/discuss/37036/my-java-solution-basic-recursion-with-backtracking

https://leetcode.com/discuss/37809/accepted-recursive-java-solution-easy-to-understand

https://leetcode.com/discuss/37077/just-iterate-all-combinations-of-c-n-k-no-dfs

https://leetcode.com/discuss/7181/what-time-complexity-recursive-solution-this-problem-how-get

posted @ 2015-11-22 23:20  YRB  阅读(954)  评论(0编辑  收藏  举报