前言
在做回溯时,常常遇到需要去重的情况,以及各种各样的条件限制。
万变不离其宗,只需要在回溯的 for 循环中第一行加入判断条件即可。
去重
排序去重
子集去重
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { private List<List<Integer>> res = new ArrayList<>(); private LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) { Arrays.sort(nums); backtrack(nums, 0); return res; }
private void backtrack(int[] nums, int start) { res.add(new ArrayList<>(path));
for (int i = start; i < nums.length; i++) { if(i > start && nums[i] == nums[i - 1]) continue; path.add(nums[i]); backtrack(nums, i + 1); path.removeLast(); } } }
|
HashSet 去重
递增子序列去重
因为原数组没法动,要直接找到里面递增的子序列,所以没法直接排序
用到了 HashSet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution { private List<List<Integer>> res = new ArrayList<>(); private LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> findSubsequences(int[] nums) { backtrack(nums, 0); return res; }
private void backtrack(int[] nums, int start){ if(path.size() > 1){ res.add(new ArrayList<>(path)); }
Set<Integer> set = new HashSet<>();
for(int i = start; i < nums.length; i++){ if(!path.isEmpty() && path.getLast() > nums[i] || set.contains(nums[i])) continue;
set.add(nums[i]);
path.add(nums[i]); backtrack(nums, i + 1); path.removeLast(); } } }
|
更多的条件
全排列去重
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| class Solution { private List<List<Integer>> res = new ArrayList<>(); private LinkedList<Integer> path = new LinkedList<>(); private boolean[] used;
public List<List<Integer>> permuteUnique(int[] nums) { if(nums.length == 0) return res; used = new boolean[nums.length]; backtrack(nums); return res; }
private void backtrack(int[] nums){ if(path.size() == nums.length){ res.add(new ArrayList<>(path)); }
Set<Integer> set = new HashSet<>();
for(int i = 0; i < nums.length; i++){ if(used[i] == true || set.contains(nums[i])) continue;
set.add(nums[i]);
used[i] = true; path.add(nums[i]);
backtrack(nums);
path.removeLast(); used[i] = false; } } }
|