[leetcode] 40. 组合总和 II

40. 组合总和 II

这题跟上题做法几乎一样,只不过每个数能取多次改成了最多能取一次,同时candidates可能会出现相同字符,感觉还没有上一个题难。

代码仅需改两处即可,直接看代码把,有注释的地方即是改过的

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<>();
        if (candidates.length == 0) return new ArrayList<>();
        Arrays.sort(candidates);
        for (int k = 1; k <= candidates.length; k++) {
            dfs(k, 0, candidates, new ArrayList<>(), 0, target, ans);
        }
        // 由于candidates可能会出现重复,所以我们对结果集做下去重即可
        return ans.stream().distinct().collect(Collectors.toList());
    }

    public void dfs(int k, int i, int[] candidates, List<Integer> now, int nowCnt, int target, List<List<Integer>> ans) {
        if (nowCnt > target) {
            return;
        }
        if (k == 0 && nowCnt == target) {
            ans.add(new ArrayList<>(now));
            return;
        }
        if (i >= candidates.length) return;
        int num = candidates[i];

        // 取多次改成了最多能取一次,也就是从0~多改成了0~1。
        for (int j = 0; j <= 1; j++) {
            if (nowCnt + j * num > target) {
                break;
            }
            for (int q = 1; q <= j; q++) {
                now.add(num);
            }
            dfs(k - j, i + 1, candidates, now, nowCnt + j * num, target, ans);
            // 回溯的时候需要注意,现在只需要rm一个就好了
            if (j == 1) {
                now.remove(Integer.valueOf(num));
            }
        }

    }
}
posted @ 2018-07-19 22:04  ACBingo  阅读(300)  评论(0编辑  收藏  举报