Loading...

回溯-有重复项数字的全排列

在这里插入图片描述

求解代码

 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] 才跳过呢?

这里可能有点绕,主要是因为:

如果当前元素前一个元素重复,且前一个元素没被使用,那么选当前元素的所有递归分支,和选前一个元素的递归分支,是完全一模一样的!

直白一点就是,前一个重复元素都没选,你还选当前这个,纯属多此一举,还会制造重复,必须剪掉!

最后更新于 2026-04-05 17:35:33
Code Road Record