47. Permutations II(全排列II)(Java)

题目链接:https://leetcode.com/problems/permutations-ii/

这道题和上一道题很类似,只不过这次给的全排列中有重复的数字,上一题

相比较于递归时重复判断的开销,对数组进行排序是利大于弊的(时间花费上)。

然后就是对排序的数组如何去重,

这道题中我只对上一题的代码加了三行就可以了。

AC 2ms beats 99% Java:

class Solution {
    List<List<Integer>> list=new ArrayList();
    public List<List<Integer>> permuteUnique(int[] nums) {
        Arrays.sort(nums);//1
        boolean[] flag=new boolean[nums.length];
        helper(nums,flag,new ArrayList<Integer>());
        return list;
    }
    public void helper(int[] nums,boolean[] flag, List<Integer> curList){
        if(curList.size()==nums.length){
            list.add(new ArrayList(curList));
            return;
        }
        for(int i=0;i<nums.length;i++){
            if(!flag[i]){
                flag[i]=true;
                curList.add(nums[i]);
                helper(nums,flag,curList);
                curList.remove(curList.size()-1);
                flag[i]=false;
                while(i<nums.length-1&&nums[i]==nums[i+1]){//2
                    i++;//3
                }
            }
            
        }
    }
}

至于这个while循环为啥放在if判断里面,其实很简单,举个例子。

排好序后,比如有1 1 1 1 1 2

当i==0时,进入if判断,将第一个1中对应的flag数组值更新为true,这就意味着在深度遍历的这一层

后面的1都是重复的1,要丢弃,同时,从这一层再往下一层,下一个1对应的flag为false,仍然可以进行

if里面的语句。

同时注意,在这种情况下,while循环只能放在flag[i]=false;的后面,否则会出现遗漏的情况。

猜你喜欢

转载自blog.csdn.net/God_Mood/article/details/87968839