LeetCode 47 全排列II

2020-09-18  本文已影响0人  嗷嗷嗷嗷_

给定一个可包含重复数字的序列,返回所有不重复的全排列。

示例:

输入: [1,1,2]
输出:
[
    [1,1,2],
    [1,2,1],
    [2,1,1]
]

思路 + 代码

本题很容易想到要用 深度遍历+回溯剪枝 来进行解答,主要难点在于所给数组中存在相同数字,即如何在回溯过程中就剪枝去重
首先对数据升序排列,在同一层递归中,如果后面一个数字和前面一个数字一样,且这两个数字都没被使用过,在for循环中,后面这个数字就可以直接跳过,没必要再重复一次dfs。

剪枝思路示例
class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {

        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList();
        List<Integer> path = new ArrayList();
        boolean[] used = new boolean[nums.length]; //记录某元素是否已经使用过

        dfs(nums,0, nums.length,used, res, path);

        return res;
    }

    public void dfs(int[] nums, int depth, int len, boolean[] used, List<List<Integer>> res, List<Integer> path){
        if (depth == len){ 
            // 成功条件
            res.add(new ArrayList(path));
            return;
        }

        for (int i = 0; i < len; i++){
            if (used[i]) continue; // 已经用了直接过
           
            // 剪枝核心,
            if (i > 0 && nums[i] == nums[i-1] && !used[i-1]) continue;
            
            // 递归以及回溯主代码
            used[i] = true;
            path.add(nums[i]);
            dfs(nums, depth + 1, len, used, res, path);
            path.remove(path.size()-1);
            used[i] = false;
        }
    }
}

上一篇 下一篇

猜你喜欢

热点阅读