40.组合总和II

172 阅读1分钟

题目

image.png

方法

  • 关键在于去重复
  • 125 215 只能留一个
  • 分支间不能重复,分之内可以选择重复数字

IMG_9F2E7776E896-1.jpeg

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

    public void dfs(int[] candidates, int start, int sum, int target) {
        if (sum == target) {
            res.add(new ArrayList<>(path));
            return;
        }
        for (int i = start; i < candidates.length; i++) {
            // !visited[i - 1]用于去除同层重复而不是同分枝重复
            // 同分枝内visited[i-1]=true, 分支间visited[i - 1]=false
            if (i - 1 >= 0 && candidates[i] == candidates[i - 1] && !visited[i - 1]) {
                continue;
            }
            if (sum + candidates[i] > target) {
                continue;
            }
            path.add(candidates[i]);
            visited[i] = true;
            dfs(candidates, i + 1, sum + candidates[i], target);
            path.remove(path.size() - 1);
            visited[i] = false;
        }
    }
}

错误解法:

IMG_4812FC12E434-1.jpeg

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

    public void dfs(int[] candidates, int start, int sum, int target) {
        if (sum == target) {
            res.add(new ArrayList<>(path));
            return;
        }
        for (int i = start; i < candidates.length; i++) {
            // 这么写,2,2,2 target=2会返回[2,2]
            if (i - 1 >= 0 && candidates[i] == candidates[i - 1] && visited[i - 1]) {
                continue;
            }
            if (sum + candidates[i] > target) {
                continue;
            }
            path.add(candidates[i]);
            dfs(candidates, i + 1, sum + candidates[i], target);
            path.remove(path.size() - 1);
            visited[i] = true;// 这么写,2,2,2 target=2会返回[2,2]
        }
    }
}