//实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 
//
// 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 
//
// 必须 原地 修改,只允许使用额外常数空间。 
//
// 
//
// 示例 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 
// 
// Related Topics 数组 
// 👍 984 👎 0

/*
* 31 下一个排列
* 2021-03-07 10:34:32
* @author oxygenbytes
*/ 
#include "leetcode.h" 
//leetcode submit region begin(Prohibit modification and deletion)

/*
 * 那么是如何得到的呢,我们通过观察原数组可以发现
 * 如果从末尾往前看,数字逐渐变大,到了2时才减小的,然后再从后往前找第一个比2大的数字,是3
 * 那么我们交换2和3,再把此时3后面的所有数字转置一下即可,步骤如下:

    1  2  7  4  3  1

    1  2  7  4  3  1

    1  3  7  4  2  1

    1  3  1  2  4  7
 */
class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int n = nums.size();
        if(n <= 1) return ;

        int i = n - 2;
        int j = n - 1;

        while(i >= 0 && nums[i] >= nums[i+1]) i--;
        if(i >= 0){
            while(nums[j] <= nums[i]) --j;
            swap(nums[i], nums[j]);
        }
        reverse(nums.begin() + i + 1, nums.end());
    }
};
//leetcode submit region end(Prohibit modification and deletion)