题目链接:https://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]
.
思路:
1、获取数组下标的全排列,然后将每个排列转化为数组元素的排列,再将结果放入HashSet中去除重复解。其中判断cur前所有下标和当前下标是否冲突需要一次for循环即for (int j = 0; j < cur; j++) ,导致超时。
2、在上述思路的基础上,用空间换时间,用used数组标记 nums数组元素的下标是否被用过。对每个下标无需判断是否和前面的是否冲突,即省略了一个for循环,提交果然AC了O(∩_∩)O~~
算法1:超时
int[] nums;
List<List<Integer>> iLists = new ArrayList<List<Integer>>();
HashSet<List<Integer>> hs = new HashSet<List<Integer>>();
List<Integer> list = new ArrayList<Integer>();
int cl[]; // 存放排列结果
int per[];// 存放排列数组下标
public List<List<Integer>> permuteUnique(int[] nums) {
this.nums = nums;
cl = new int[nums.length];
per = new int[nums.length];
dspPermute(0);
iLists.addAll(hs);
return iLists;
}
void dspPermute(int cur) {
if (cur == nums.length) {
hs.add(new ArrayList<Integer>(list));
} else {
for (int i = 0; i < nums.length; i++) { // 探索每一列
per[cur] = i;// 数组下标的组合
boolean flag = true;
for (int j = 0; j < cur; j++) {// cur前所有行 若无冲突
if (per[cur] == per[j])
flag = false;
}
if (flag == true) {
list.add(nums[per[cur]]);
dspPermute(cur + 1);
list.remove(list.size() - 1);
}
}
}
}
算法2:
int[] nums;
List<List<Integer>> iLists = new ArrayList<List<Integer>>();
HashSet<List<Integer>> hs = new HashSet<List<Integer>>();
List<Integer> list = new ArrayList<Integer>();
int cl[]; // 存放排列结果
int per[];// 存放排列数组下标
boolean used[];//表示数组下标是否被使用过
public List<List<Integer>> permuteUnique(int[] nums) {
this.nums = nums;
cl = new int[nums.length];
per = new int[nums.length];
used = new boolean[nums.length];
dspPermute(0);
iLists.addAll(hs);
return iLists;
}
void dspPermute(int cur) {
if (cur == nums.length) {
hs.add(new ArrayList<Integer>(list));
} else {
for (int i = 0; i < nums.length; i++) { // 探索每一列
if(used[i]) //如果该下标被用过
continue;
per[cur] = i;// 数组下标的组合
used[i] = true;
list.add(nums[per[cur]]);
dspPermute(cur + 1);
list.remove(list.size() - 1);
used[i]=false;//记得要复原,否则走到底后used数组全为true,跟list要remove道理一样
}
}
}