问题描述
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].
思考:如何避免重复
想法
1、将PermutationsI中的list换成map,利用map的key唯一性,避免重复
1、将num中的元素当作map的key,将出现次数作为value,设n为 待插入数目(初始为num.length),调用 recurPermutation(map, curNum, result, n);
如果value大于0,则讲key插入curNum列表,并将key的value - 1,
3、将n置为n - 1,递归,
4、递归之后,将curNum和map复原(curNum移除key,map中key的value + 1),返回2步,继续循环2、将问题视为位置调换(leetcode 会超时,本地测试没有问题)
1、先将num排序,初始化i = 0,i为换位的位置 2、设k = i, k < n, k++ 以此将k与i位交换,递归i + 1位 3、递归之后将k与i位换回,并进行下次循环
代码
想法1
public class Solution {
public List<List<Integer>> permuteUnique(int[] num) {
List<List<Integer>> result = new LinkedList<List<Integer>>();
if(num.length == 0)
return result;
Map<Integer, Integer> map = new HashMap<>();
List<Integer> curNum = new LinkedList<Integer>();
for(int i = 0; i < num.length; i++)
if(map.containsKey(num[i]))
map.put(num[i], map.get(num[i]) + 1);
else
map.put(num[i], 1);
recurPermutation(map, curNum, result, num.length);
return result;
}
private void recurPermutation(Map<Integer, Integer> map, List<Integer> curNum, List<List<Integer>> result, int n){
if(n <= 0){
result.add(new LinkedList<Integer>(curNum));
return;
}
Set<Integer> keys = map.keySet();
Iterator<Integer> it = keys.iterator();
while(it.hasNext()){
Integer key = it.next();
Integer value = map.get(key);
if(value <= 0) continue;
map.put(key, --value);
curNum.add(key);
recurPermutation(map, curNum, result, n - 1);
curNum.remove(curNum.size() - 1);
map.put(key, ++value);
}
}
}
想法2
public class Solution {
public List<List<Integer>> permuteUnique(int[] num) {
List<List<Integer>> result = new LinkedList<List<Integer>>();
if(num.length == 0)
return result;
Arrays.sort(num);
recurSwap(num, 0, num.length, result);
return result;
}
private void recurSwap(int[] num, int index, int end, List<List<Integer>> result){
if(index == end - 1){
List<Integer> l = new LinkedList<>();
for(int i:num)
l.add(i);
result.add(l);
return;
}
for(int k = index; k < end; k++){
if(k != index && num[k] == num[index]) continue;
swap(index,k,num);
recurSwap(num, index + 1, end, result);
swap(index,k,num);
}
}
private void swap(int i, int j, int[] num){
int temp = num[j];
num[j] = num[i];
num[i] = temp;
}
}