[LeetCode-Java]31. Next Permutation

本文介绍了一个算法,用于在原地将数组中的元素重新排列成字典序中下一个更大的排列。如果不存在这样的排列,则将数组变为最小可能的顺序(升序)。文章详细解释了两种情况的处理方法,并提供了一个具体的Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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, do not allocate 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)从后往前查询,中间有一个位(记为位置p)破坏递增规律。则需要从其后选一个比它大且最靠近它的数相交换,剩下的位递增排列即可。而要实现这个效果,考虑到位置p之后的位都是递减排列,只要从最后一位往前查询,遇到的第一位比它大的数即满足条件(比它大且最靠近它),交换二者位置后,p后面的所有位是递减排列,因而再把p后面的所有位逆序排列即可。

public void nextPermutation(int[] nums) {

        int position = 0;

        for (int i = nums.length-1;i>0;i--){
            if (nums[i]>nums[i-1]){
                //从最后一位往前查询,找到第一个不是递增的数  其位置为position
                position = i - 1;
                break;
            }
            //此时原来的排序为最大值,把数组逆序即可。
            if (i == 1){
                reverse(nums,0);
                return;
            }
        }

        for (int j = nums.length - 1;j>position;j--){
            //从后往前查询,找到第一个比nums[position]大的数,交换其位置,position后面的所有位逆序
            if (nums[j] > nums[position]){
                int temp = nums[j];
                nums[j] = nums[position];
                nums[position]  = temp;
                reverse(nums,position+1);
                break;
            }
        }

    }

    void reverse(int[] num,int index)
    {

        int lo = index;
        int hi = num.length - 1;

        while (lo<hi){
            int temp = num[hi];
            num[hi] = num[lo];
            num[lo] = temp;
            lo++;
            hi--;
        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值