LeetCode每日一题 (56) 31. 下一个排列(这个排序的下一个大点的排序,两找交换一反转)

在这里插入图片描述

具体地,我们这样描述该算法,对于长度为 n 的排列 a:

一(找)、首先从后向前查找第一个顺序对 (i,i+1),满足a[i] < a[i+1]这样「较小数」即为 a[i]a[i]。此时 [i+1,n) 必然是下降序列。

二(找)、如果找到了顺序对,那么在区间 [i+1,n) 中从后向前查找第一个元素 j 满足 a[i] < a[j]。这样「较大数」即为 a[j]a[j]。

三(反转)、交换 a[i] 与 a[j]此时可以证明区间 [i+1,n) 必为降序。我们可以直接使用双指针反转区间 [i+1,n)使其变为升序,而无需对该区间进行排序。

class Solution {
    
    
public:
    void nextPermutation(vector<int>& nums) {
    
    
        // 找到一个较小的i
        int i=nums.size()-2;
        while(i>=0 && nums[i]>=nums[i+1]){
    
    
            i--;
        }
        // 从最后开始找第一个出现的j比i小的数
        if(i>=0){
    
    
            int j=nums.size()-1;
            while(j>=0 && nums[j]<=nums[i]){
    
    
                j--;
            }
            swap(nums[i],nums[j]);
        }
        // 对i以后的数反转 反转以后就是排好序的
        reverse(nums.begin()+i+1,nums.end());
    }
};

在这里插入图片描述


猜你喜欢

转载自blog.csdn.net/qq_45021180/article/details/109609430