Description
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
Example
Input: [1,1,2]
Output: [ [1,1,2], [1,2,1], [2,1,1] ]
解题思路
承接46
注意把函数中now remove的时候不要用remove(Object obj),用remove(int index),因为这次里面有重复的数字
然后在最后加个去重(List 转 Set)
class Solution {
public void getList(List<Integer> now, List<List<Integer>> all, List<Integer> cur){
if(cur.isEmpty()){
all.add(new ArrayList<>(now));
return;
}
for(int i = 0; i < cur.size(); i++){
Integer temp = cur.get(i);
cur.remove(i);
now.add(temp);
getList(now, all, cur);
cur.add(i, temp);
now.remove(now.size() - 1);
}
}
public List<List<Integer>> permuteUnique(int[] nums) {
List<Integer> s = new ArrayList<>();
for(int i = 0; i < nums.length; i++){
s.add(nums[i]);
}
List<Integer> now = new ArrayList<>();
List<List<Integer>> all = new ArrayList<>();
getList(now, all, s);
//return all;
return new ArrayList<>(new HashSet(all));
}
}
emmmm一种比较好的方法是不用每次移来移去,设置一个boolean的visit数组用来存放是否被访问
然后在最开始的时候,对数组进行排序,让相同的数字位于同一地方,这样在更新的时候,碰到相同的数字,只要移动到不同数字的地方再往后递归,就不需要进行去重的操作。
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
permutation(nums, res, new ArrayList<Integer>(), new boolean[nums.length]);
return res;
}
private void permutation(int[] nums, List<List<Integer>> res, List<Integer> tmp, boolean[] visited) {
if (tmp.size() == nums.length) {
res.add(new ArrayList<>(tmp));
return;
}
for (int i = 0; i < nums.length; i++) {
if(visited[i] || (i > 0 && !visited[i - 1] && nums[i] == nums[i - 1])) continue;
visited[i] = true;
tmp.add(nums[i]);
permutation(nums, res, tmp, visited);
tmp.remove(tmp.size() - 1);
visited[i] = false;
}
}
}