Leetcode 47. Permutations II

该博客探讨了两种解决整数数组独特全排列问题的方法。方法1基于回溯,通过排序输入数组并跳过重复元素来避免重复。方法2同样采用回溯,但通过设置集合来跟踪已使用的元素。这两种方法都是对经典全排列问题的优化,适用于需要排除重复排列的情况。

在这里插入图片描述
方法1: 和46题方法2一样,就是多加一个判断条件。

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        if(nums.length == 1){
            List<Integer> ans = new ArrayList<>();
            ans.add(nums[0]);
            res.add(ans);
            return res;
        }
        Arrays.sort(nums);
        for(int i = 0; i < nums.length; i++){
            if(i != 0 && nums[i] == nums[i-1]) continue;
            int curr = nums[i];
            List<List<Integer>> list = permuteUnique(reconstruct(nums, i));
            for(List<Integer> l : list) {
                l.add(0, curr);
                res.add(l);
            } 
        }
        return res;
    }
    
    public int[] reconstruct(int[] nums, int i){
        int[] res = new int[nums.length-1];
        boolean flag = true;
        for(int j = 0; j < res.length; j++){
            if(j != i && flag){
                res[j] = nums[j];
            }else{
                flag = false;
                res[j] = nums[j + 1];
            }
        }
        return res;
    }
}


方法2: 46题的方法1的修改,加了一个set。这个set是相对于recursive level的而不是全局的。

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> nums_list = new ArrayList<>();
        Arrays.sort(nums);
        for(int num : nums) nums_list.add(num);
        int len = nums.length;
        backtrack(len, 0, nums_list, res);
        return res;
    }
    
    public void backtrack(int len, int start, List<Integer> path, List<List<Integer>> res){
        if(start == len){
            res.add(new ArrayList<>(path));
            return;
        }
        Set<Integer> set = new HashSet<>();
        for(int i = start; i < len; i++){
             if(set.add(path.get(i))){
                Collections.swap(path, start, i);
            	backtrack(len, start+1, path, res);
            	Collections.swap(path,start, i);
             } 
        }
    }
}

总结:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值