LeetCode_Medium_31. Next Permutation

过春节休息了几天,今天继续开始刷。。

2019.2.10

题目描述:

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,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

 

又是一道每个字都认识,连起来就一脸懵逼的题。。思来想去也没啥头绪,只好点开讨论与谷歌搜索起来。。。。。

解法一:

看完之后发现也是一个找规律的题目。。。解题思路如下:

  1. 判断按照字典序有木有下一个,如果完全降序就没有下一个,即变为完全升序的初试序列
  2. 如何判断有木有下一个呢?只要存在a[i-1] < a[i]的升序结构,就有,而且我们应该从右往左找,一旦找到,因为这样才是真正下一个
  3. 当发现a[i-1] < a[i]的结构时,从在[i, ∞]中找到最接近a[i-1]并且又大于a[i-1]的数字,由于降序,从右往左遍历即可得到k
  4. 然后交换a[i-1]与a[k],然后对[i, ∞]排序即可。

举个例子,比如[0,5,4,3,2,1],从后往前遍历发现1-2-3-4-5均是升序,到了5-0的时候变为了降序,则再从后往前遍历找寻第一个比0大的数,是1,那么交换0和1,然后把1后面的数全部排序即可

C++代码:

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int temp=INT_MAX,n,k;
        for(n=nums.size()-2;n>=0;n--)
            if(nums[n]<nums[n+1]) break;
        if(n==-1){
            sort(nums.begin(),nums.end());
            return;
        }
        for(int i=n+1;i<nums.size();i++){
            if(nums[i]>nums[n]&&nums[i]<temp){
                temp=nums[i];
                k=i;
            }
        }
        swap(nums[n],nums[k]);
        sort(nums.begin()+n+1,nums.end());
    }
};

这题也是典型的想得出就做得出,想不出就嗝屁的题目。。。

解法二:官方解法

Java代码:

public class Solution {
    public void nextPermutation(int[] nums) {
        int i = nums.length - 2;
        while (i >= 0 && nums[i + 1] <= nums[i]) {
            i--;
        }
        if (i >= 0) {
            int j = nums.length - 1;
            while (j >= 0 && nums[j] <= nums[i]) {
                j--;
            }
            swap(nums, i, j);
        }
        reverse(nums, i + 1);
    }

    private void reverse(int[] nums, int start) {
        int i = start, j = nums.length - 1;
        while (i < j) {
            swap(nums, i, j);
            i++;
            j--;
        }
    }

    private void swap(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、付费专栏及课程。

余额充值