Leetcode 31. 下一个排列

地址 https://leetcode-cn.com/problems/next-permutation/

实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须 原地 修改,只允许使用额外常数空间。


示例 1:
输入:nums = [1,2,3]
输出:[1,3,2]

示例 2:
输入:nums = [3,2,1]
输出:[1,2,3]

示例 3:
输入:nums = [1,1,5]
输出:[1,5,1]


示例 4:
输入:nums = [1]
输出:[1]
 

提示:
1 <= nums.length <= 100
0 <= nums[i] <= 100

解答

观察找规律

小数由左向右是升序

123456

大数由左向右是降序

654321

那么小数向大数转换成最接近的一个大数

我们需要从右向左找到第一个不符合升序的数字 然后 再从右向左找到第一个比它大的数字的数字进行交换

比如 1234  找到第一个不符合升序的数字3 3比4小 再从右向左找到第一个比它大的数字4 进行交换 变成1243即可

额外的交换后的数字比原来的数字排列要大 但是未必是最接近的数字,因为交换后的位置的右边数字是大数的升序排列而不是降序排列,需要处理一下

例如  1 3 4 2 找到第一个不符合升序的数字3 在找到交换的数字4 变换成1 4 3 2 这时候 3 2比 2 3要大

还需要进行一个小范围的降序处理  ,1 4 2 3才是正解

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int i = 0;
        for ( i = nums.size() - 2; i >= 0; i--) {
            if (nums[i] < nums[i + 1]) {
                for (int j = nums.size() - 1; j > i; j--) {
                    if (nums[j] > nums[i]) {
                        swap(nums[i], nums[j]);
                        reverse(nums.begin() + i + 1, nums.end());
                        return;
                    }
                }
            }
        }

        if (i < 0) {
            reverse(nums.begin(), nums.end());
            return;
        }
        
        return;
    }
};
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
阿里打赏 微信打赏
原文地址:https://www.cnblogs.com/itdef/p/14569821.html