【LeetCode #31 题解】 下一个排列

本LeetCode 算法系列文章分类导航:《【LeetCode】 高效算法刷题思路、算法题目分类 - 持续更新
本文链接: 《【LeetCode #31 题解】 下一个排列


题目

题目链接:《31. 下一个排列

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

分析思路

这个题可以转换为,寻找下一个比它更大的数。

例如,以 [ 1 , 5 , 8 , 4 , 7 , 6 , 5 , 3 , 1 ] [ 1,5,8,4,7,6,5,3,1] [158476531]为例。

  1. [ 1 , 5 , 8 , ( 4 ) , 7 , 6 , 5 , 3 , 1 ] [ 1,5,8,(4),7,6,5,3,1] [158(4)76531]中,从末尾开始找,找到第一个不是降序非列的数 4 4 4

  2. 接着在 [ 7 , 6 , ( 5 ) , 3 , 1 ] [ 7,6,(5),3,1] [76(5)31]中找到第一个比 4 4 4 更大的数 5 5 5, 交换 5 5 5 4 4 4
    结果为: [ 1 , 5 , 8 , ( 5 ) , 7 , 6 , ( 4 ) , 3 , 1 ] [ 1,5,8,(5),7,6,(4),3,1] [158(5)76(4)31]

  3. 最后将 [ 7 , 6 , 4 , 3 , 1 ] [ 7,6,4,3,1] [76431] 做升序处理,为 [ 1 , 3 , 4 , 6 , 7 ] [ 1,3,4,6,7] [13467]

  4. 最终输出结果为 : [ 1 , 5 , 8 , ( 5 ) , 1 , 3 , ( 4 ) , 6 , 7 ] [ 1,5,8,(5),1,3,(4),6,7] [158(5)13(4)67]

图示动画如下:
在这里插入图片描述

c++ 代码实现:

// 示例:  
// 1,3,5,8,6,4,2,1
// (1) 从末尾寻找第一个破坏升序的数:5
// (2) 在 8,6,4,2,1 中寻找第一个 大于它的数,6, 交换后的结果 1,3,[6],8,[5],4,2,1
// (3) 将 8,5,4,2,1 按升序排列 ,即 1,2,4,5,8
// (4) 最终结果输出,1,3,[6],1,2,4,[5],8

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        // 获得最大长序
        int pos = nums.size() - 1; 
        cout << "数组大小为:"<< pos + 1 << endl;

        // 1. 从末尾寻找第一个破坏降序的数
        while(pos > 0 && nums[pos] <= nums[pos-1])
            pos--;
        
        // 2. 找到第一个比它大的数,交换
        if(pos > 0){
            cout << "找到数字为: pos="<<pos-1 << " num="<<nums[pos-1] << endl;
            
            for(int i = nums.size()-1 ; i>=pos ; i--){
                if(nums[i] > nums[pos-1]){
                    cout << "交换" <<nums[pos-1] << "和" << nums[i]<< endl; 
                    swap(nums[pos-1], nums[i]);
                    break;
                }
            }
        }

        // 3. 升序排列
        reverse(nums.begin() + pos, nums.end());
    }
};

提交结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

"小夜猫&小懒虫&小财迷"的男人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值