Leetcode1-100: 31. Next Permutation

Leetcode1-100: 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,31,3,2
3,2,11,2,3
1,1,51,5,1
题目要求: 输入一个整型数组,输出按照数值大小为顺序的下一个排列

解题思路

这题拿到手需要先分析一下,如何找到大小排序的下一个排列? 可以按照数字的大小来比较,最后一位是个位,倒数第二位是十位,然后是百位,千位……然后只需要将其中的几位数字换一下位置即可。首先从后往前找,找到第一个开始变小的数字,这个时候只需要把这个变小后的数字,跟它后面一位比它大一些的数字调换即可。例如132719643210这个数字,从最后一位0开始往后找,找到第一个开始下降的数字1,把1跟后面比它大的一个数字换即可,因为需要的是next permutation,所以找到的值不能太大,只能找到刚好比它大的数字2,所以换成了132729643110,这时候实现了增大.因为这里后面的数字都是按照顺序递减的,所以按顺序一个一个找即可。但是可以看到最后几位是9643110,很显然不是当前前面位数13272开头能组成的最小数字,所以后面的数字直接排序一下即可。由于这里的数字也都是倒序排列的,所以直接颠倒一下位置即可。132719643210 → 132729643110 → 132720113469

代码实现

	//当时写的时候没考虑到后面是有序的数组,所以用了Arrays.sort()所以时间复杂度应该会稍微高一些
   public void nextPermutation(int[] nums) {
        if(nums.length == 0) return;
        reverseArray(nums, nums.length);
        for(int i = 0; i < nums.length-1; i++) {
            if(nums[i] > nums[i+1]) {
                for(int j = 0; j<=i; j++) {
                    if(nums[j]>nums[i+1]) {
                        int temp = nums[j];
                        nums[j] = nums[i+1];
                        nums[i+1] = temp;
                        break;
                    }
                }
                Arrays.sort(nums,0,i+1);
                reverseArray(nums, i+1);
                reverseArray(nums, nums.length);
                return;
            }
        }
        Arrays.sort(nums);
    }
    public void reverseArray(int[] nums, int end) {
        for(int head = 0, tail = end-1-head; head<=tail; head++, tail--) {
            int temp = nums[head];
            nums[head] = nums[tail];
            nums[tail] = temp;
        }
    }

在这里插入图片描述
复杂度分析:

时间复杂度:O(nlogn) (如果没用sort而是直接颠倒的话时间复杂度就是O(n))
空间复杂度:O(1) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值