一、问题描述
- 给定一个数组nums,数组中是包含重复元素的,返回所有的不重复的排列结果。
- 例子:
输入数组为[1,1,2],返回结果为:
[ [1,1,2],[1,2,1],[2,1,1] ]
二、解题思路
- 还是按照LeetCode-46中的想法,固定部分元素求其余部分元素排列的方式,但是因为数组有重复元素,所以想要增加以下两点考虑:
- 关于首位元素
下面代码中当i为0时,代表固定0个元素,即求所有元素的排列,这样每个元素都会轮流当首位元素,但是因为有重复,所以需要一个list记录当过首位元素的值,如果一个值当过首位元素,则其后相同的值都不允许做首位元素。同理,i=1代表固定一个元素,排列其余的元素,首位元素的处理也是按照这种思路。 - 2说的两种情况,本以为可以通过先将数组排序,然后将两个判断条件压缩为仅判断nums[j]==nums[j-1]。但是,这样是有问题的,比如求00019的排列形式,中间会出现09010,如果按照这种思路,固定数字9,2和3的数字交换,然后2和4的数字还会交换,这样0就做了两遍头,本质还是因为交换导致的数组不再是递增数组。
三、代码
public class Solution {
List<List<Integer>> result=new ArrayList<List<Integer>>();
public List<List<Integer>> permuteUnique(int[] nums) {
if(nums==null || nums.length==0)
return result;
permuteCore(nums,0);
return result;
}
private void permuteCore(int[] nums,int i){
if(i==nums.length-1){
List<Integer> list=new ArrayList<Integer>();
for(int k=0;k<nums.length;k++){
list.add(nums[k]);
}
result.add(list);
return;
}
List<Integer> temlist=new ArrayList<Integer>();
for(int j=i;j<nums.length;j++){
if((temlist.contains(nums[j])))
continue;
temlist.add(nums[j]);
int tem=nums[i];
nums[i]=nums[j];
nums[j]=tem;
permuteCore(nums,i+1);
nums[j]=nums[i];
nums[i]=tem;
}
}
}