1.题目描述:
给定一个可包含重复数字的序列nums,按任意顺序返回所有不重复的全排列。
2.回溯:
在leetcode46. 全排列基础上增加去重操作,由于数组包含重复元素,不能用全排列中list.contains()方法,在原代码基础上套入leetcode40. 组合总和 II的使用标记数组去重代码即可。
class Solution {
private List<List<Integer>> resList = new ArrayList<>();
private List<Integer> list = new ArrayList<>();
private boolean[] flag;
public List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
flag = new boolean[nums.length];
backTracking(nums);
return resList;
}
public void backTracking(int[] nums) {
if (list.size() == nums.length) {
resList.add(new ArrayList<>(list));
return;
}
for (int i = 0; i < nums.length; i++) {
if (flag[i] || i > 0 && nums[i] == nums[i - 1] && !flag[i - 1]) continue;
//flag[i]排除重复调用;后者保证了回溯后同一树层相邻的两个元素相同的情况即树层去重
//这里!flag[i - 1]改成flag[i - 1]也可,相当于树枝上去重,但是效率低
flag[i] = true;
list.add(nums[i]);
backTracking(nums);
list.remove(list.size() - 1);
flag[i] = false;
}
}
}