每天一道算法题:31. 下一个排列(Next Permutation)

1 问题

1.1 英文描述

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 中文描述

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

来源:力扣(LeetCode)

1.3 题意解释

  • 输入为一个数组,比如说[1,2,3],我们可以把它当做是一个整数123
  • 然后我们需要找出比123大的下一个数字,这里就是132(这里的下一个数必须由[1,2,3]组成,不能使用未在数组中出现的数字),所以我们的输出为[1,3,2]。
  • 如果给的输入已经是最大的数了,那么就需要找出最小的那个数,例如,如果输入为[3,2,1],那么输出就为[1,2,3]。

2 解答

2.1 解题思路

  1. 我们需要从输入的整数数组的尾部开始,往前进行遍历,找到两个数字,其中前面的数字比后面的数字小
索引012345
113221
  1. 这里我们发现nums[1] < nums[2],定义一个partition = 1,然后查找partition索引后面比nums[1]大的数字中最小的一个,如果有相同的数字,则取索引最大的数字,最后交换这两个数字
索引01(partiton)2345
123211
  1. 最后一步,把partition后面的数组进行逆序操作。
索引01(partiton)2345
121123

2.2 代码实现

class Solution {
    public void nextPermutation(int[] nums) {
        int length = nums.length;
        int partition = -1;
        // 从数组尾部开始找,当相邻两个,后面大于前面时,前面那个作为partition
        for (int i = length - 1; i > 0; i--) {
            if (nums[i] > nums[i - 1]) {
                partition = i - 1;
                break;
            }
        }
        int temp;
        // 从partition索引后面找一个比nums[partition]大且是最接近的元素,进行交换
        if (partition != -1) {
            int index = partition + 1;
            for (int i = partition + 2; i < length; i++) {
                if (nums[partition] < nums[i] && nums[i] <= nums[index]) {
                    index = i;
                }
            }
            temp = nums[partition];
            nums[partition] = nums[index];
            nums[index] = temp;
        }

        // 逆序partition后的元素
        int i = partition + 1;
        int j = length - 1;
        while (i < j) {
            temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
            i++;
            j--;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值