
求解代码
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
|
ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
public ArrayList<ArrayList<Integer>> permuteUnique (int[] num) {
ArrayList<Integer> track = new ArrayList<>();
boolean[] used = new boolean[num.length];
Arrays.sort(num);
backtrack(num, track, used);
return ans;
}
private void backtrack(int[] num,ArrayList<Integer> track,boolean[] used){
if(track.size()==num.length){
ans.add(new ArrayList<>(track));
return;
}
for(int i=0;i<num.length;i++){
if(used[i]){
continue;
}
if(i>0&&num[i]==num[i-1]&&!used[i-1]){
continue;
}
track.add(num[i]);
used[i]=true;
backtrack(num, track, used);
track.remove(track.size()-1);
used[i]=false;
}
}
|
小贴士
在代码层面,这道【有重复项数字的全排列问题】和【没有重复项数字的全排列问题】不同的就是增加了一个排序语句和一个if语句。
其中,排序是为了让重复元素相邻,后续只需要判断相邻的重复元素即可。
那下面的if语句为什么是!used [i-1] 才跳过呢?
这里可能有点绕,主要是因为:
如果当前元素和前一个元素重复,且前一个元素没被使用,那么选当前元素的所有递归分支,和选前一个元素的递归分支,是完全一模一样的!
直白一点就是,前一个重复元素都没选,你还选当前这个,纯属多此一举,还会制造重复,必须剪掉!