欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

#leetcode刷题之路31-下一个排列

程序员文章站 2022-06-26 10:15:22
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。必须原地修改,只允许使用额外常数空间。 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。1,2,3 → 1,3,23,2,1 → 1,2, ......

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

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

 

思路:1.尝试一次遍历就解决问题。从后向前遍历数组,如果后一个总是比前一个大,那么排列就是最大的,这时需要反转排列。

2.如果在遍历过程中发现了一个比之前一个小的数,位置为i(此时i后面的数以降序排列,是最大值),此时反过来向后遍历,找到后面部分中最后一个比这个数大的数,交换两数(此时位置i后面的数降序排列,不过比之前的小),这时,i后面的数依然以降序排列,是最大值,但是我们想要得到的是下一个更大的排列,因此我们需要把i后面的数反序。即:小+最大排列-->大+最小排列

 

#include <iostream>
#include <vector>

using  namespace std;

void reverse(int begin,int end,vector<int>& nums)//用于反转序列
{
    while(begin<end)
    {
        int temp=nums[begin];
        nums[begin]=nums[end];
        nums[end]=temp;
        begin++;
        end--;
    }
}


void nextpermutation(vector<int>& nums) {
    int i;
    int len=nums.size();
    if(len==0||len==1) return;
    if(len==2) {reverse(0,1,nums);
        return;}
    for(i=len-2;i>=0;i--)
    {
        if(nums[i]>=nums[i+1]) continue;
        else break;
    }
    if(i==-1) reverse(0,len-1,nums);
        //i记录要交换的位置
    else
    {
        for(int j=len-1;j>=i+1;j--)
        {
            if(nums[j]>nums[i])
            {
                int t=nums[j];
                nums[j]=nums[i];
                nums[i]=t;
                reverse(i+1,len-1,nums);
                break;
            }
        }
    }
}

int main() {
    vector<int> a={1,3,2};
    nextpermutation(a);
    std::cout <<a[0] <<a[1]<<a[2]<< std::endl;
    return 0;
}