排列问题的回溯,如T46的所说的那几个问题,没有start,同时我们看此题所说可以包含重复数字,那么我们就需要分辨这个重复数字是指树枝
还是树层
,回看一下题目,元素在同一个组合内是可以重复的,怎么重复都没事,但两个组合不能相同,所以我们可以知道要去重的是同一树层上的“使用过”,同一树枝上的都是一个组合里的元素,不用去重。
class Solution {
List<List<Integer>> result = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> permuteUnique(int[] nums) {
boolean[] used = new boolean[nums.length];
Arrays.fill(used, false);
Arrays.sort(nums);
dfs(nums, used);
return result;
}
private void dfs(int[] nums, boolean[] used) {
if (path.size() == nums.length) {
result.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < nums.length; i++) {
// used[i - 1] == true,说明同⼀树⽀nums[i - 1]使⽤过
// used[i - 1] == false,说明同⼀树层nums[i - 1]使⽤过
// 如果同⼀树层nums[i - 1]使⽤过则直接跳过
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
continue;
}
//如果同⼀树⽀nums[i]没使⽤过开始处理
if (used[i] == false) {
used[i] = true;//标记同⼀树⽀nums[i]使⽤过,防止同一树支重复使用
path.add(nums[i]);
dfs(nums, used);
path.removeLast();//回溯,说明同⼀树层nums[i]使⽤过,防止下一树层重复
used[i] = false;//回溯
}
}
}
}