文章目录
先分析一下这道题目的区别,
首先46题题中要求是不含重复元素,所以我们在进行回溯的时候不需要对数据进行去重、
其次47题题中说明了含有重复元素,所以我们在进行回溯过程中需要对数据进行去重。那么我们怎么去重呢?
上面两道题我们使用传统的回溯写法很容易就可以写出来,但是对于47题难点是对数据进行去重,这里我们需要解释一下卡子哥自创的树枝去重和树层去重
我们用树化的思维去寻找符合条件的值,存在多个同一个数的时候,在同一个树枝上可以重复,对于同一层来说,如果再取这个数据就会出现重复,一般用一个used数据来表示,不太理解的话可以先记住,多做几道题就理解了。(我大概遇到五六道题就慢慢理解了)。
树层去重:
if(i>0 && num[i] == nums[i-1] && used[i-1] == false)
树枝去重:
if(i>0 && num[i] == nums[i-1] && used[i-1] == true)
这里我给出两道题的示例代码,仔细品一品吧。
全排序I
class Solution { List<List<Integer>> list = new ArrayList<>(); LinkedList<Integer> list1 = new LinkedList<>(); boolean[] used; public List<List<Integer>> permute(int[] nums) { if(nums.length == 0){ list.add(new ArrayList<>(list1)); return list; } used = new boolean[nums.length]; HiSir(nums); return list; } public void HiSir(int[] nums){ if(list1.size() == nums.length){ list.add(new ArrayList<>(list1)); return; } for(int i = 0;i<nums.length;i++){ if(used[i]){ continue; } used[i] = true; list1.add(nums[i]); HiSir(nums); used[i] = false; list1.removeLast(); } } }
全排序II
class Solution { List<List<Integer>> list = new ArrayList<>(); LinkedList<Integer> list1 = new LinkedList<>(); boolean[] used; public List<List<Integer>> permuteUnique(int[] nums) { if(nums.length == 0){ list.add(new ArrayList<>(list1)); return list; } used = new boolean[nums.length]; Arrays.fill(used,false); Arrays.sort(nums); HiSir(nums); return list; } public void HiSir(int[] nums){ if(list1.size() == nums.length){ list.add(new ArrayList<>(list1)); return; } for(int i =0;i<nums.length;i++){ if(i >0 && nums[i] == nums[i-1] && used[i-1] == false){ continue; } if(used[i] == false){ used[i] = true; list1.add(nums[i]); HiSir(nums); list1.removeLast(); used[i] = false; } } } }