【Leetcode 每日一题】40. 组合总和 II

问题背景

给定一个候选人编号的集合 c a n d i d a t e s candidates candidates 和一个目标数 t a r g e t target target,找出 c a n d i d a t e s candidates candidates 中所有可以使数字和为 t a r g e t target target 的组合。
c a n d i d a t e s candidates candidates 中的每个数字在每个组合中只能使用 一次
注意:解集不能包含重复的组合。

数据约束

  • 1 ≤ c a n d i d a t e s . l e n g t h ≤ 100 1 \le candidates.length \le 100 1candidates.length100
  • 1 ≤ c a n d i d a t e s [ i ] ≤ 50 1 \le candidates[i] \le 50 1candidates[i]50
  • 1 ≤ t a r g e t ≤ 30 1 \le target \le 30 1target30

解题过程

算是回溯的例题,由于结果不能重复,要先将数组进行排序,方便在过程中跳已经处理过的相等元素。

具体实现

递归

class Solution {

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        dfs(0, target, candidates, res, path);
        return res;
    }

    private void dfs(int i, int target, int[] candidates, List<List<Integer>> res, List<Integer> path) {
        if(target == 0) {
            res.add(new ArrayList(path));
            return;
        }
        if(i == candidates.length) {
            return;
        }
        int cur = candidates[i];
        if(target < cur) {
            return;
        }
        path.add(cur);
        dfs(i + 1, target - cur, candidates, res, path);
        path.remove(path.size() - 1);
        i++;
        while(i < candidates.length && candidates[i] == cur) {
            i++;
        }
        dfs(i, target, candidates, res, path);
    }
}

递推

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        dfs(0, target, candidates, res, path);
        return res;
    }

    private void dfs(int i, int target, int[] candidates, List<List<Integer>> res, List<Integer> path) {
        if(target == 0) {
            res.add(new ArrayList<>(path));
            return;
        }
        for (int j = i; j < candidates.length && candidates[j] <= target; j++) {
            if(j > i && candidates[j] == candidates[j - 1]) {
                continue;
            }
            path.add(candidates[j]);
            dfs(j + 1, target - candidates[j], candidates, res, path);
            path.remove(path.size() - 1);
        }
    }
}

你可能感兴趣的:(Leetcode,Daily,leetcode,算法,数据结构)