排列问题

字符串的全排列

求一个字符串的全排列可以看成是两步。第一步求所有可能出现在第一个第一个位置的字符,即把第一个位置如后面所有的字符交换,这里需要注意:如若字符串中有重复字符,那么重复的字符中只需要其中一个换作首字母。第二步固定第一个字符,求后面所有字符串的全排列,可以这是一个递归操作。

代码示例(以int整形数字为例)

 vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<vector<int>> res;
        if(nums.empty()) return res;
        permute(nums,res,nums.size(),0);
        return res;
    }
     void permute(vector<int>& nums,vector<vector<int>>& numlist,int length,int begin)
    {
        if(begin==length)
        {
            //递归截止条件,并保存当前排列至结果vector
            numlist.push_back(nums);
            return;
        }
        set<int> helper;  //用于保存已经出现在首位的字符
        for(int i=begin;i<length;++i)
        {
            if(helper.empty()) 
                helper.insert(nums[i]);
            //判断该字符在首位中是否已经出现过,若出现过,则直接跳过
            else if(helper.find(nums[i])!=helper.end())
                continue;
            else
                helper.insert(nums[i]);
            //将当前字符与首字符交换
            int tmp=nums[i];
            nums[i]=nums[begin];
            nums[begin]=tmp;

            //固定首位,递归遍历其余位
            permute(nums,numlist,length,begin+1);

            //将之前交换的位置换回来
            tmp=nums[i];
            nums[i]=nums[begin];
            nums[begin]=tmp;


        }
    }

字符串的下一个排列

  下一个排列即是按照字典序寻找当前字符串排列的下一个更大的排列,如若不存在下一个更大的排列,则将字符串排列成最小的排列!
  首先从字符串尾部开始遍历,找到第一对i 和 ii,使得 i=ii-1 且str[i]

 void nextPermutation(vector<int>& nums) {
        if(nums.empty()) return;
        int end=nums.size()-1;
        int i,ii,j;
        for(int ii=end;ii>0;--ii)
        {
            i=ii-1;
            //知道满足条件的i和ii
            if(nums[i]<nums[ii])
            {
                for(j=end;j>=0;j--)
                {
                    //找到满足条件的j
                    if(nums[j]>nums[i])
                    {
                        //交换i和j所在位置元素值
                        swap(nums[i],nums[j]);
                        //对ii之后所有元素作逆序操作
                        reverse(nums.begin()+ii,nums.end());
                        return;
                    }
                }
            }
        }
        //若不满足条件,则对整个数字串作逆序操作
        reverse(nums.begin(),nums.end());
        return;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值