https://oj.leetcode.com/problems/permutations-ii/
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]
public List<List<Integer>> permuteUnique(int[] num)
问题分析:这题和permutation的关系其实和combination sum跟combination sum II的关系是一样的。都是input有重复,但是output不能有重复。
但是这题不能像combination sum那样利用sort和前后判断来简单的回避解集的重复。
本身其实也可以,但有两个条件限制了它不可以:
1.在combination sum的要求里,每一个元素集合的输出是顺序的,这里不是,一旦利用了sort,那么就会和leetcode里面的解集产生顺序上的不同。
2.我的做法是inplace的,一旦产生了swap,那么之前的sort就会失去它本身的意义,最终导致了重复解集的输出。所以说如果是非inplace的做法,利用一个buf作为输出的缓冲和Boolean数组作为路径是否经过的判断,那么sort的做法也还是有意义的。但是还是会有第一个条件的问题。
下面给出代码如下:
public List<List<Integer>> permuteUnique(int[] num) {
List<List<Integer>> res = new LinkedList<List<Integer>>();
helper(res, 0, num);
return res;
}
public void helper(List<List<Integer>> res, int curlevel, int[] num){
if(curlevel == num.length){
LinkedList<Integer> cur_res = new LinkedList<Integer>();
for(int i : num)cur_res.add(i);
res.add(cur_res);
}
else{
for(int i = curlevel; i < num.length; i++){
boolean flag = false;
for(int j = curlevel; j < i; j++){
if(num[j] == num[i]){//这是我们跳过重复解集的办法,我们没办法只和路径上前一个元素比较,但是我们依然可以与走过的路径进行比较。只是要遍历
flag = true;
break;
}
}
if(flag)
continue;
int tmp = num[curlevel];
num[curlevel] = num[i];
num[i] = tmp;
helper(res, curlevel + 1, num);
num[i] = num[curlevel];
num[curlevel] = tmp;
}
}
}