题目描述

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

示例 1:

输入:nums = [1,2,3]

输出:[1,3,2]

示例 2:

输入:nums = [3,2,1]

输出:[1,2,3]

示例 3:

输入:nums = [1,1,5]

输出:[1,5,1]

链接:https://leetcode-cn.com/problems/next-permutation

解题思路

1.首先数组中从后往前寻找,升序排列的第一个位置i,使得nums[i] <nums[i+1]

2.在[1+1,n]中寻找一个最小的输nums[j]使得nums[j]大于nums[i]

3.交换nums[i]与nums[j]的位置,然后翻转子数组[i+1,n]

代码实现

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        bool isFind = false;
        int n = nums.size();
        int i = n - 2;
        //寻找升序排列的第一个位置i,使得nums[i] <nums[i+1]
        for(; i >= 0; i--){
            if(nums[i] < nums[i + 1]){
                isFind = true;
                break;
            }
                
        } 
        //在[1+1,n]中寻找一个最小的输nums[j]使得nums[j]大于nums[i]
        if(isFind){
            int k = i + 1;
            for(int j = i + 1; j < n; j ++){
                if(nums[j] > nums[i] && nums[j] <= nums[k]){
                        k = j;
                }
            }  
            swap(nums[i], nums[k]); 
        }
        else{
            i = -1;
        }   
        //翻转子数组[i+1,n]    
        int mid = (n - i)/2;
        for(int k = 1; k <= mid; k ++){
            swap(nums[i + k], nums[n - k]);
        }
    }
};