47 全排列 II

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

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

方法1:递归回溯
主要思路:更详细题解参考官方题解
(1)这里和46 全排列使用的思路不太一样,在 46 全排列中由于不存在重复的元素,故直接在原始的数组中进行交换操作,本题中存在重复的元素,故将原数组排序后,只是作为遍历的对象,中间结果另存为一个数组中;
(2)这样的话,就需要一个标志数组来标识当前数组是否被访问过vector sign(nums.size(),false);
(3)同时,为了去除重复的元素,需要增加去除可能的重复的结果的判断,既 if(i>0&&nums[i]==nums[i-1]&&!sign[i-1]);
(4)其他的操作是正常的递归回溯方式;

 void helper(vector<int>&nums,int depth,vector<int>& tmp,vector<bool>&sign, vector<vector<int>>& res){
 		//终止条件,既深度满足要求
        if(!depth){
            res.push_back(tmp);
            return;
        }
		//遍历数组
        for(int i=0;i<nums.size();++i){
        	//不能再次访问已经访问过的元素
            if(sign[i])
                continue;
            //去重操作,既当前选择和前一个选择相同,当前一个选择显示没有访问,
            //说明同一层的之前选择已经访问过了,现在是同一层的后面相同的选择,故直接跳过
            if(i>0&&nums[i]==nums[i-1]&&!sign[i-1])
                continue;
            tmp.push_back(nums[i]);//压入可行的选择
            sign[i]=true;//将对应的选择标识
            helper(nums,depth-1,tmp,sign,res);//继续递归回溯
            tmp.pop_back();//恢复选择之前的状态,以是同层的后续的选择可以进行
            sign[i]=false;//将对应的选择的标识恢复
        }
    }

    vector<vector<int>> permuteUnique(vector<int>& nums) {
    	//处理特殊的情形
        if(nums.empty())
            return vector<vector<int>>();
        //排序原数组
        sort(nums.begin(),nums.end());
        vector<vector<int>> res;
        vector<int> tmp;
        vector<bool> sign(nums.size(),false);//标识数组元素的访问情形
        helper(nums,nums.size(),tmp,sign,res);//递归回溯
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值