Leetcode 31. Next Permutation 记一道一开始题目都没看懂的题

本文深入解析LeetCode中关于数字序列排列的难题,探讨如何寻找序列的下一个排列,包括理解和实现算法步骤,如查找递增位置、交换元素及逆序操作。

上题目:

 

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,3”的全排列,依次是:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

 

这是一个什么样的顺序的,其实就是数值从小到大

 

所以题目给我们一串数字,我们需要找出这串数字在序列中的下一个 例如  1 3 2的下一个就是 2 1 3

而如果是最后一个 那么就找到第一个,例如 3 2 1的下一个是  1 2 3
 

 

解法:

知道规则后,就可以开始解题了。

可以明确的是,一个数字序列(除了最后一个)的下一个要比前一个数值大,但又是比它大的数值当中最小的

所以我们可以理解leetcode里面的一个举例

6 5 4 8 7 5 1
 

首先肯定从后面开始看,1和5调换了没有用。

7、5和1调换了也没有效果,因此而发现了8、7、5、1是递减的。

如果想要找到下一个排列,找到递增的位置是关键。

因为在这里才可以使其增长得更大。

于是找到了4,显而易见4过了是5而不是8或者7更不是1。

因此就需要找出比4大但在这些大数里面最小的值,并将其两者调换。

那么整个排列就成了:6 5 5 8 7 4 1

然而最后一步将后面的8 7 4 1做一个递增。

 

 

代码:

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值