标题:47全排列II-中等
题目
给定一个可包含重复数字的序列
nums
,按任意顺序 返回所有不重复的全排列。
示例1
输入:nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]
示例2
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
提示
1 <= nums.length <= 8
-10 <= nums[i] <= 10
代码Java
List<List<Integer>> ans = new ArrayList<>();
List<Integer> temp = new ArrayList<>();
boolean[] flag = null;
public List<List<Integer>> permuteUnique(int[] nums) {
if (nums == null || nums.length == 0) return ans;
flag = new boolean[nums.length];
Arrays.sort(nums);
backTracking(nums);
return ans;
}
public void backTracking(int[] nums) {
if (temp.size() == nums.length) {
// if (!ans.contains(temp)) // 去重 方法笨拙 效率很低
ans.add(new ArrayList<>(temp));
return;
}
for (int i = 0; i < nums.length; i++) {
// 1. 当前两个条件i > 0 和 nums[i] == nums[i - 1] 成立时
// 说明前一个位和后一位相同
// 有以下两种方式:
// 1.1 flag[i - 1] == true,说明同一树枝nums[i - 1]使用过
// true时,说明前后一致,且上一次被使用过了,因为一次次往下遍历,因此是树枝
// 1.2 flag[i - 1] == false,说明同一树层nums[i - 1]使用过
// false时,前后一致,但前一次没有被使用过,说明已经返回到同一层了,被回溯为false了
// 2. 此题对树枝和树层都可进行去重
// 2.1 树层去重效率更好,更直接
if (i > 0 && nums[i] == nums[i - 1] && flag[i - 1] == false )
continue;
if (!flag[i]) {
flag[i] = true;
temp.add(nums[i]);
backTracking(nums);
flag[i] = false;
temp.remove(temp.size() - 1);
}
}
}