【DFS】全排列II

一、题目

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/7p8L0Z/

二、题解

在全排列1的基础上,全排列2要求结果集合中不能有重复,在进行dfs的时候就需要进行剪枝,比如序列【1 1 1 2】,首先枚举结果的每一个位置的情况,第一个位置可以是选择序列中0下标的1,那么序列中下标位1 2 的元素对于的也是1就不能选择了,如果第一个位置选择1,在选择第二个位置的时候序列中下标是0的1刚才被选做结果集合的第一个位置的元素因此不能选择,接着序列中下标是1的元素1是可以作为结果序列的第二个位置的值,接着序列中2下标对应的元素1,就不能作为结果序列的第二个位置元素了,因为结果序列的第二个位置已经选择过元素1了,此时不能选择,所以在进行dfs过程中需要进行两步的剪枝:1.已经选择过的元素不可在选择,通过全局的check数组可以解决 2. 当前位置上已经选择过的元素不能选择

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path, nums;
    int n;
    bool check[10];

    void dfs(int u) {
        if (u == n) {
            res.push_back(path);
            return;
        }

        for (int i = 0; i < n; i++) {
            // 如果当前元素被 选了 或者 当前元素等于前面一个元素且前面的元素没有没选那么这样就会发生重复,此时进行剪枝
            if (check[i] || (i != 0 && (nums[i] == nums[i - 1] && !check[i - 1]))) continue;
                path.push_back(nums[i]);
                check[i] = true;
                dfs(u + 1);
                check[i] = false;
                path.pop_back();
                continue;
        }
    }

    vector<vector<int>> permuteUnique(vector<int>& _nums) {
        nums = _nums;
        n = nums.size();
        sort(nums.begin(), nums.end());
        
        dfs(0);
        return res;
    }
};
class Solution {
    List<List<Integer>> ans;
    List<Integer> path;
    int[] nums;
    boolean check[];
    int n;


    void dfs(int u) {
        if (u == n) {
            ans.add(new ArrayList<>(path));
            return;
        }

        for (int i = 0; i < n; i++) {
            if (i == 0 && !check[0]) {
                path.add(nums[i]);
                check[i] = true;
                dfs(u + 1);
                check[i] = false;
                path.remove(path.size() - 1);
                continue;
            } 
               if (!check[i] && (i != 0 && nums[i] != nums[i-1] || !check[i - 1])) {
                path.add(nums[i]);
                check[i] = true;
                dfs(u + 1);
                check[i] = false;
                path.remove(path.size() - 1);
            }
        }
    }


    public List<List<Integer>> permuteUnique(int[] _nums) {
        nums = _nums;
        Arrays.sort(nums);
        n = nums.length;
        ans = new ArrayList<>();
        path = new ArrayList<>();
        check = new boolean[n];

        dfs(0);
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值