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

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

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
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;
}

 

posted @ 2019-03-20 11:33  maitianpt  阅读(196)  评论(0编辑  收藏  举报