LeetCode下一个排列

LeetCode: Next Permutation

问题描述

A permutation of an array of integers is an arrangement of its members into a sequence or linear order.

  • For example, for arr = [1,2,3], the following are considered permutations of arr: [1,2,3], [1,3,2], [3,1,2], [2,3,1].

The next permutation of an array of integers is the next lexicographically greater permutation of its integer. More formally, if all the permutations of the array are sorted in one container according to their lexicographical order, then the next permutation of that array is the permutation that follows it in the sorted container. If such arrangement is not possible, the array must be rearranged as the lowest possible order (i.e., sorted in ascending order).

  • For example, the next permutation of arr = [1,2,3] is [1,3,2].
  • Similarly, the next permutation of arr = [2,3,1] is [3,1,2].
  • While the next permutation of arr = [3,2,1] is [1,2,3] because [3,2,1] does not have a lexicographical larger rearrangement.

Given an array of integers nums, find the next permutation of nums.

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

Example1

Input: nums = [1,2,3]
Output: [1,3,2]

Example2

Input: nums = [3,2,1]
Output: [1,2,3]

Example3

Input: nums = [1,1,5]
Output: [1,5,1]

方法思路

一个特定数组中有多个整数,本题的目的是求这个数组中各个整数进行重新排列并根据数组数值大小进行排序后,所有情况中仅仅比本身数组大一点的情况,如果这个数组已经是最大的数组了,那么则求排列所有情况中的最小数组。首先我们需要分析一些数组来找打重新排列的规律。

在这里插入图片描述
在这里插入图片描述
怎样才能使数组在重新排列后只比之前大一点,最有效的方法就是在倒数第一个数大于倒数第二个数的调换他们的位置,对于数组 [1,2,3,4], 就只需要交换3,4的位置,因此可以得出对于一个递增的数组,只需要交换它最后两个整数的位置,而对于一个递减的数组,则不能交换,因为它本身已经最大了,就像数组 [4,3,2,1],所以我们要做的就是将一个数组分为多个递增或者递减数组,对于数组 [1,3,2,5],我们知道它是先递增后递减再递增,对于最后的递增数组,我们找到它是 [2,5],交换他们的位置即可,对于数组 [7,6,8,7],我们知道它是先递减再递增再递减,最后的递增数组是 [6,8], 本来应该是交换他们的位置,但是因为它后面还存在一个递减数组,如果还需要再进行一次遍历,找出在这个递减数组中比6大的最小的数,可以得出是7,这一步只需要从后向前遍历即可,因为它是递减数组前面的必然比后面的大,交换位置后数组变成 [7,7,8,6], 对于递减数组 [8,6],我们要使它变成最小的递增数组,通过转置(inverse)来实现,对于将完全的递减数组变成完全的递增数组,同样适用,因为它整个可以被看做最后一个递减数组,最后就大公告成了!

代码如下(示例):

class Solution {
    public void nextPermutation(int[] nums) {
        int i = nums.length - 1;
        
        //Find the index of integer which is not the first element of a sequence with descending order
        while(i!=0){
            if(nums[i] > nums[i-1]){
                break;
            }
            i--;
        }
        
        //Find the index behind this element which is larger than it and switch them
        int j = nums.length - 1;
        int m = i - 1;
        while(j != m && m != -1){
            if(nums[j] > nums[m]){
                int t = nums[j];
                nums[j] = nums[m];
                nums[m] = t;
                break;
            }
            j--;
        }
        
        //Inverse array behind this element to have and ascending order
        j = nums.length - 1;
        while(i<j){
            int t = nums[j];
            nums[j] = nums[i];
            nums[i] = t;
            i++;
            j--;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值