Loading

LeetCode 40 组合总数II

LeetCode40 组合总数II

题目描述

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次

样例

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
  [1,2,2],
  [5]
]

算法分析

与上一题的区别:本体是限制了选取的次数

int k = u;
while(k < candidates.length && candidates[u] == candidates[k]) k++;

//所以candidates[u]有 k-u个
int cnt = k - u;

时间复杂度

Java代码

class Solution {
    static List<List<Integer>> ans = new ArrayList<List<Integer>>();
    static void dfs(int[] candidates, int target, int u, int sum, List<Integer> t){
        if(sum > target) return;
        if(u == candidates.length){
            if(sum == target) ans.add(new ArrayList<Integer>(t));
            return;
        } 


        int k = u;
        while(k < candidates.length && candidates[u] == candidates[k]) k++;

        //所以candidates[u]有 k-u个
        int cnt = k - u;
        for(int i = 0; i <= cnt && sum + candidates[u] * i <= target; i++){
            //跳到下一个不同的数字
            dfs(candidates, target, k, sum + i * candidates[u], t);
            t.add(candidates[u]);
        }

        for(int i = 0; i <= cnt && sum + candidates[u] * i <= target; i++){
            t.remove(t.size() - 1);
        }
    }

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        ans.clear();
        List<Integer> t = new ArrayList<Integer>();
        dfs(candidates, target, 0, 0, t);
        return ans;
    }
}
posted @ 2020-11-03 14:16  想用包子换论文  阅读(68)  评论(0)    收藏  举报