LeetCode90. 子集 II

☆☆☆☆思路:回溯 + 剪枝。 如果使用Set去重,不能AC

class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums); // 排序
        dfs(nums, 0, new ArrayList<>(), res);
        return res;
    }
    // 举例:[1,2,2]
    // 去重前:[ [],[1],[1,2],[1,2,2],[1,2],[2],[2,2],[2] ]
    // 去重后:[ [],[1],[1,2],[1,2,2],[2],[2,2] ]
    private void dfs(int[] nums, int start, List<Integer> list, List<List<Integer>> res) {
        res.add(new ArrayList<>(list));
        for (int i = start; i < nums.length; i++) {
            // 和上个数字相等就跳过, 注意是 i > start, 而不是大于0
            // 在一个for循环中,所有被遍历到的数都是属于一个层级的。我们要让一个层级中,必须出现且只出现一个2
            // i > start 可以让同一层级,不出现相同的元素;但允许不同层级之间的重复
            // eg. 如果把所有当前与之前一个元素相同的都砍掉,那么第二个2出现的时候,已经和前一个2相同了。
            if (i > start && nums[i] == nums[i-1]) continue;
            list.add(nums[i]);
            dfs(nums, i + 1, list, res);
            list.remove(list.size() - 1);
        }
    }
}

 

posted @ 2020-12-28 12:30  不学无墅_NKer  阅读(71)  评论(0编辑  收藏  举报