【leetcode】47 全排列II(回溯)

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

题目描述

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

示例:

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

思路

这题与 题46 全排列 类似,都是用回溯的思路解决,主要区别在于需要去重

1 回溯

(1)首先需要对数组进行排序
(2)去重通过判断进行

if(i!=begin && nums[i] == nums[begin])   continue; // 如果后续有重复数字 不需要交换
  • 注意传入的nums是拷贝不是引用!引用会导致nums改变,而使得判断条件失效导致重复
  • 并且swap(nums[i],nums[begin]); 只需要执行一次,不需要再恢复现场。恢复现场反而会导致判断条件失效引起重复。

以[1,1,2,2] 为例,如果交换完位置1和2的元素后,为[1,2,1,2],如果恢复现场,则nums又变为[1,1,2,2] 此时交换位置1和3的元素(begin = 1,i=3, nums[begin] =1 != 2 = nums[i] 去重条件失效),又为[1,2,1,2],造成重复。

所以该解法中 拷贝复制+去重条件+不用恢复现场是环环相扣的,缺一不可。

class Solution {
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<vector<int>> ret;
        if(nums.empty()) return ret;
        sort(nums.begin(), nums.end());
        permuteUniqueCore(nums,0,ret);
        return ret;
    }

private:
    void permuteUniqueCore(vector<int> nums, int begin, vector<vector<int>>& ret){	// 注意传入的nums不是引用!!是拷贝
        if(begin>= nums.size()){                    // 到达最后元素,打印
            ret.push_back(nums);
            return;
        }
        for (int i = begin; i < nums.size(); ++i) {
            if(i!=begin && nums[i] == nums[begin])   // 如果后续有重复数字 不需要交换
                continue;
            swap(nums[i],nums[begin]);
            permuteUniqueCore(nums, begin+1, ret);  // begin+1递归
        }
    }
};

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值