不使用next_permutation(),计算下一个字典序更大的数组排列

思路:

因为数组变化的幅度要尽可能的小,所以我们需要在数组靠右边部分操作(交换数值)。

方法:两遍扫描

我们需要将一个左边的「较小数」与一个右边的「较大数」交换,以能够让当前排列变大,从而得到下一个排列。

同时我们要让这个「较小数」尽量靠右,而「较大数」尽可能小。当交换完成后,「较大数」右边的数需要按照升序重新排列。这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。

1)从末端开始遍历,寻找非降序的元素,记录下标

2)从末端开始,找到第一个大于上面元素的元素下标

3)交换数值,并且对后续的排列逆序

 算法代码如下:

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
    int right=nums.size()-1,front,i=right,end;
    for(;i>=1;i--)
        if(nums[i]>nums[i-1])
            {front=i-1;break;}              //找到非降序元素
    if(front==right)                        //纯增序
    reverse(nums.begin(),nums.end());
    else
    { 
        if(front<0)                        //纯降序
        {
            front=right-1;
            end=right;
        }
        else
        {
        for(i=right;i>=front;i--)
            if(nums[i]>nums[front])
                {end=i;break;}             //找到首个大于降序元素的元素下标
        }
        swap(nums[front],nums[end]);
        for(i=front+1;i<right;i++,right--)
        {
            swap(nums[i],nums[right]);
        }
    }
}
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值