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;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_41637618/article/details/86756004