leetcode 力扣 39 组合总和

77 阅读1分钟

回溯

使用减法,确定下一次dfs要找的数。比如下面的例子,[2, 3, 6, 7]7 - 2 = 55就是下一次dfs要找的数,如果能把5减到0,那么就找到一组答案[2, 2, 3]

  • 第一个问题,如何避免重复?比如[2, 2, 3][2, 3, 2]。我们可以在每次dfs入口,将for循环起始数设置为当前下标。比如[2, 3, 2],在3准备往下递归时,将起始数(begin)设置为1,下一次递归就是从3开始,当然最后一个3要剪枝(如下图)。

  • 第二个问题,如何剪枝?如下图左下角,1 - 2 = -1, 1 - 3 = -2, 1 - 6 = -5, 1 - 7 = -6,所以我们可以从第一个-1就开始剪枝,用break退出当前循环即可。当然前提是将数组排好序。

1.jpeg

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    Deque<Integer> combination = new ArrayDeque<>();

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        dfs(candidates, target, 0);
        return res;
    }

    public void dfs(int[] candidates, int target, int begin) {
        if (target == 0) {
            res.add(new ArrayList(combination));
            return;
        }

        for (int i = begin; i < candidates.length; i++) {
            if (target - candidates[i] < 0) {
                break;
            }

            combination.addLast(candidates[i]);
            dfs(candidates, target - candidates[i], i);
            combination.removeLast();
        }
    }
}