天天看点

LeetCode ---- 40、组合总和 II

题目链接

思路:

这道题与39题思路一致,只是在添加结果的过程中,要做到不重复,那么需要在回溯的过程中进行剪枝,当出现与之前数相同时,需要跳过这个数不选。

public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> res = new ArrayList<>();
        if (candidates == null || target < 1) {
            return res;
        }
        // 先给数组排序,方便后续处理
        Arrays.sort(candidates);
        dfs(candidates, target, 0, new ArrayDeque<Integer>(), res);
        return res;
    }
    /**
     *   做减法
     * @param candidates   
     * @param target     需要加到的目标和
     * @param index      数组元素当前下标
     * @param path       存储每次选中的元素
     * @param ans        最终的结果
     */  
    private void dfs(int[] candidates, int target, int index, Deque<Integer> path,             
                                                     List<List<Integer>> res) {
        // 当目标值减到0时,说明此时选择的数字满足要求
        if (target == 0) {
            res.add(new ArrayList(path));
            return ;
        }
        for (int i = index; i < candidates.length; i++) {
            // 如果之前的剩余的和减去当前数字小于0,则不符合要求,直接跳出循环
            if (target - candidates[i] < 0) {
                break;
            }
            // 如果当前数字跟前一个数字相同,则跳过当前数字,因为前一个数字已经选中了
            if (i > index && candidates[i] == candidates[i - 1]) {
                continue;
            }
            path.addLast(candidates[i]);
            // 开始尝试下一个位置的数
            dfs(candidates, target - candidates[i], i + 1, path, res);
            path.removeLast();
        }
    }
           

代码参考自:https://leetcode-cn.com/problems/combination-sum-ii/solution/hui-su-suan-fa-jian-zhi-python-dai-ma-java-dai-m-3/