每天一道算法题:31. Next Permutation

01 问题描述

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

02 解题思路

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

03 代码实现

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