求当前排列的下一个排列的方法在我之前的博客中,排列是有序的
http://blog.csdn.net/github_31804537/article/details/52848094
而这个是不停的找下一个排列,直到和第一个重复,就说明依旧全部遍历了
public class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
Set set = new HashSet<List<Integer>>();//不用set也行,list也有contains()方法,但set速度快了list很多,这道题用set,22ms,不用set,57ms
List<Integer>list = new ArrayList<>();
List<List<Integer>>ll = new ArrayList<>();
Arrays.sort(nums);
adc(list,nums);
set.add(list);
for(int i =0;;i++){
list= new ArrayList<>();
nextPermutation(nums);
adc(list,nums);
if(set.contains(list))break;
set.add(list);
}
ll.addAll(set);
return ll;
}
private void adc(List<Integer>list,int[] nums){//普通的把数组放入list中
for(int i=0;i<nums.length;i++)
list.add(nums[i]);
}
//从这开始就是找下一个排序
private void nextPermutation(int[] nums) {
if(nums.length<=1)return;
int i = nums.length-1;
for(;i>=1;i--){
if(nums[i-1]<nums[i])
break;
}
int first = i-1;
int second = i;
if(i!=0){
int j =nums.length-1;
for(;j>i-1;j--){
if(nums[j]>nums[first])break;
}
swap(nums,first,j);
}
reverse(nums,second,nums.length-1);
}
private void swap(int[]nums,int i,int j){
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
private void reverse(int []nums,int start,int end){
int i=start;
int j=end;
while(i<j){
swap(nums,i,j);
i++;
j--;
}
}
}