6.组合总和

题目描述

给你一个无重复元素的整数数组candidates和一个目标整数target,找出candidates中可以使数字和为目标数target的所有不同组合,并以列表形式返回。你可以按任意顺序返回这些组合。
candidates中的同一个 数字可以无限制重复被选取。如果至少一个数字的被选数量不同,则两种组合是不同的。 
对于给定的输入,保证和为target的不同组合数少于150个。

题目链接

https://leetcode-cn.com/problems/combination-sum/

复杂度

时间复杂度:
O(S):
其中S为所有可行解的长度之和。
O(n*2的n次方)是一个比较松的上界,因为n个位置每次考虑选或者不选,如果符合条件,就加入答案的时间代价。
但是实际运行的时候,因为不可能所有的解都满足条件,递归的时候还会使用target-candidates[idx]>=0进行剪枝,所以实际运行情况是远远小于上界。
空间复杂度:
O(target)
除了答案数组之外,空间复杂度取决于递归的栈深度,在最差的情况下需要递归O(target)层

示例

示例一:

输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

示例二:

输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]

示例三:

输入: candidates = [2], target = 1
输出: []

说明

6.组合总和

代码

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> combine = new ArrayList<Integer>();

        dfs(candidates, ans, combine, target, 0);

        return ans;
    }

    public void dfs(int[] candidates, List<List<Integer>> ans, List<Integer> combine, int target, int idx) {
        if (idx == candidates.length) {
            return;
        }

        if (target == 0) {
            ans.add(new ArrayList<Integer>(combine));
            return;
        }

        dfs(candidates, ans, combine, target, idx + 1);

        if (target - candidates[idx] >= 0) {
            combine.add(candidates[idx]);
            dfs(candidates, ans, combine, target - candidates[idx], idx);
            combine.remove(combine.size() - 1);
        }
    }
}
上一篇:leetcode39 组合求和


下一篇:ios7版 30天精通iPhone手机编程 第14天 图片浏览器