0%

Leetcode 47 Permutations II

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

Example:

1
2
3
4
5
6
7
Input: [1,1,2]
Output:
[
[1,1,2],
[1,2,1],
[2,1,1]
]

1 暴力

明显可以当成leetcode 46题来做, 只不过这里要用Set<List<Integer>>.去重. 但是太慢了.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
Set<List<Integer>> ans = new HashSet<>();
boolean[] isTraversed = new boolean[nums.length];
List<Integer> curr = new ArrayList<>();
permute(ans, curr, nums, isTraversed);
return new ArrayList<>(ans);
}
private void permute(Set<List<Integer>> ans, List<Integer> curr, int[] nums, boolean[] isTraversed)
{
if(curr.size() == nums.length)
{
ans.add(new ArrayList<Integer>(curr));
return;
}
for(int i = 0; i < nums.length; ++i)
{
if(!isTraversed[i])
{
curr.add(nums[i]);
isTraversed[i] = true;
permute(ans, curr, nums, isTraversed);
curr.remove(curr.size() - 1);
isTraversed[i] = false;
}
}
}
}

2 排序去重

首先先排序.

当nums[i] == nums[i-1], 并且isTraverse[i-1] = false的时候, 直接跳过nums[i]即可. 否则一定会重!

例如 nums = [1,1,2]

第一次遍历, 先选择了第1个1, 此时curr = [1], 这时, 第1个1的isTraverse为false, 可以将第2个1假如到curr中变成curr = [1, 1],随后可以计算出符合条件的 curr = [1,1,2], curr = [1,2,1], 他们被加入到结果ans中.

第二次遍历, 选择了第2个1, 但是有nums[1] == nums[0], 并且isTraverse[0] = false, 应该跳过这一次! 如果不跳过, 就有当前的curr存储了第2个1, curr = [1], 但是第1个1的isTraverse是false, 所以还会把第1个1加入到curr中, 变成curr = [1,1]. 和上面的重复了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
boolean[] isTraversed = new boolean[nums.length];
List<Integer> curr = new ArrayList<>();
List<List<Integer>> ans = new ArrayList<>();
permute(ans, curr, nums, isTraversed);
return ans;
}
private void permute(List<List<Integer>> ans, List<Integer> curr, int[] nums, boolean[] isTraversed)
{
if(curr.size() == nums.length)
{
ans.add(new ArrayList<Integer>(curr));
return;
}
for(int i = 0; i < nums.length; ++i)
{
if(!isTraversed[i])
{
if(i > 0 && nums[i] == nums[i-1] && !isTraversed[i-1])
continue;
curr.add(nums[i]);
isTraversed[i] = true;
permute(ans, curr, nums, isTraversed);
curr.remove(curr.size() - 1);
isTraversed[i] = false;
}
}
}
}