Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2]
have the following unique permutations:
[1,1,2]
, [1,2,1]
, and [2,1,1]
.
11/3
这道题难点是怎么去掉重复的元素, 我采用的方法是对于num[i], 如果num[i-1] == num[i], 那么num[i]必须要在同样的元素之后才能插入, 比如
【1,2,3】
L【0】 = 【1】
L【1】 = 【1,2】【2,1】
L【2】=【1,2,3】【1,3,2】【3,1,2】【3,2,1】【2,3,1】【2,1,3】
而对于【1,2,2】
L【1】 是相同的,接下来在插入出现过的2的时候,
对于【1,2】, 只能插到2后头, 形成【1,2,2】
对于【2,1】, 只能形成【2,2,1】 和 【2,1,2】
就只有3个解
public class Solution {
List<List<Integer>> ans;
int len = 0;
public List<List<Integer>> permuteUnique(int[] num) {
Arrays.sort(num);
ans = new ArrayList<List<Integer>>();
len = num.length;
permuteRec(num, new ArrayList<Integer>());
return ans;
}
private void permuteRec(int[] num, List<Integer> prev){
int now = prev.size(); // the next index to consider
if(now == len){
ans.add(prev);
return;
}else{
if(now == 0 || num[now] > num[now-1]){
// insert num[now] to all the possbile position
int size = prev.size();
for(int i=0; i<=size; i++){
List<Integer> copy = new ArrayList<Integer>(prev);
copy.add(i, num[now]);
permuteRec(num, copy);
}
}else{ // num[now] > num[now-1], only add after the previous same element
int size = prev.size();
int start = size-1;
for(; start >= 0; start--){
if(prev.get(start) == num[now]) break;
}
// start > 0 has to hold
for(int i=start+1; i<=size; i++){
List<Integer> copy = new ArrayList<Integer>(prev);
copy.add(i, num[now]);
permuteRec(num,copy);
}
}
}
}
}