给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
参考全排列
在全排列I的基础上加判断当前操作元素是否前面已经存在重复即可,不存在在执行换位操作,存在跳过即可;
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
int end = nums.length - 1;
List<List<Integer>> res = new ArrayList<>();
permute(nums, res, 0, end);
return res;
}
//换位
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public void permute(int[] nums, List<List<Integer>> res, int begin, int end) {
//递归法,两两换位
//递归结束条件,两两换位后,begin = end;
if (begin == end) {// 完成一次全排列
List<Integer> temp = new ArrayList<>();
for (Integer i : nums)
temp.add(i);
res.add(temp);
return;
} else {
for (int i = begin; i <= end; i ++) {//换位
if (checkContains(nums, begin, i)) {
swap(nums, begin, i);//锁定位
permute(nums, res, begin + 1, end);//后续位
swap(nums, begin, i);//回档在进行下次换位
}
}
}
}
private boolean checkContains(int[] nums, int start, int end) {
for (int i = start; i < end; i ++) {
if (nums[i] == nums[end])//当前元素已经是重复元素
return false;
}
return true;
}
}