31. Next Permutation

31. Next Permutation
题目描述

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place and use only constant extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
这道题的意思,是要找到下一个排列。对一组数的全排列,是按照字典序大小排序的。如果目前是最大的排列,则返回最初的排列(即升序排列)。

思路

还是看了别人的思路。这道题主要的思想有两个基础:

  1. 对于一个排列来说,它的下一个排列是和它有最大公共前缀序列的一个序列
  2. 对于一个降序排序的排列,它没有下一个排列

基于这两个前提,我们可以有以下的思路:

  1. 从数组最后开始遍历排列,找到第一个a[i-1]<a[i] 的数,这代表着a[i]之后的数都是降序排列,并不存在下一个排列。
  2. 所以对于a[i-1:]这个排列,下一个排列应该是,
    (1)新的a[i-1] 应该比之前那个大一点。
    (2)a[i:] 应该是最小的排列

所以对于整个算法来说总体的思路是:

  1. 从后往前遍历数组,找到第一个使得a[i-1]<a[i]的数i
  2. 然后又从后往前找到第一个比a[i-1]大的数a[j],并将a[i-1]和a[j]交换
  3. 然后将a[i:]reverse
class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int len=nums.size();
        int i_1=len-2;
        while(0<=i_1&&nums[i_1+1]<=nums[i_1])
            i_1--;//the first violate element
        if(0<=i_1)
        {
            int i_2=len-1;
            while(i_1<i_2&&nums[i_2]<=nums[i_1])//find the first element that >= nums[i_1]
                i_2--;
            swap(nums, i_1, i_2);
        }
        reverse(nums,i_1+1);
            
    }
    void reverse(vector<int>& nums, int i)
    {
        int j=nums.size()-1;
        while(i<j)
        {
            swap(nums, i, j);
            i++;
            j--;
        }
    }
    void swap(vector<int>& nums, int i, int j)
    {
        int temp=nums[i];
        nums[i]=nums[j];
        nums[j]=temp;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值