Problem 2 Subset II with duplication

repeat

Method 1(每一层就是加不加,你只能加第一个)

这种去重问题其实本质上是backtracking里面的剪枝问题

  • 不是先产生所有的解,再用set去重==》 思想错误

  • 不产生重复的解,我知道重复我就不走

Step 1:分析为什么会发生重复,画图

Step 2:说出去重的方法

  • 处理方法:二选一

  • 也就是说,所有加的分支都照常不懂,加就是加,就正常加,但你要说不加那就再也不加了

  • 那你怎么做到要不加后面再来的也不要了?这个写法基于assumption:同样的元素都连在一起出现

    • while (index + 1 < nums.length && nums[index + 1] == nums[index]) { index++;}

    • 如果你没有了assumption,就必须需要先sort

List Version

public List<List<Integer>> subsets(int[] nums) {
    List<List<Integer>> result = new ArrayList<>();
    if (nums == null || nums.length == 0) {
        return result;
    }
    Arrays.sort(nums);
    List<Integer> current = new ArrayList<>();
    backTracking(result, nums, current, 0);
    return result;
}
// index: 当前层我正要考虑的元素
private void backTracking(List<List<Integer>> result, int[] nums, List<Integer> current, int index) {
    if (index = nums.length) {
        result.add(new ArrayList<>(current));
        return;
    }
    // add
    current.add(nums[index]);
    backTracking(result, nums, current, index + 1);
    current.remove(current.size() - 1);
    
    // not add
    while (index + 1 < nums.length && nums[index + 1] == nums[index]) {
        index++;
    }
    backTracking(result, nums, current, index + 1);

}

String Version

Method 2(只取第一个&& i == index || nums[i] != nums[i - 1] && 注意while的位置和while的条件是看在同一层,下一次加的点一不一样)

Step 1:分析为什么会发生重复,画图

  • 为什么会重复?同一层分支中,同样的元素,先加前面哪个和先加后面哪个

Step 2:说出去重的方法

  • 同一层分支中,同样的元素,我只留第一分支

  • 所以不是到了那个点吃吐,而是吃完以后,之后所有的我都不管了

  • 为了达到这个效果,我必须得用sort,因为需要把相同的放在一起·

List Version

String Version

Method 3& 4(不sorted & 用set chasing result)

这里的set:是你路过的,但是你不能使用element

  • 如果是方法1,你路过的,只有parent和children,还有上下

  • 如果是方法2,你路过的,不止是parent,还有你隔壁的children,所以是左右,还有上下

  • 这个hashSet是你之前走过路,所以info是到这一层,以及这一层你前面走过的element

Last updated