题目描述

题解
// 首先字典序的意思是,从升序排列开始,每一次排列后都找出,比上一次大的数中最小的数,
// 。比如[1, 3, 5, 6, 4],一下个排列就是[1, 3, 6, 4, 5],它是比原排列大的排列里面
// 最小的。找到下一个排列需要几个过程,如下:
// [1, 3, 5, 6, 4]
// >> [1, 3, 6, 5, 4]
// >> [1, 3, 6, 4, 5]
// 首先我们需要找到升序里面的最末位两个,把它们交换位置,变成[1, 3, 6, 5, 4],
// 此时如果这两个数的右数开始往右所有的数,本身就是升序(小在前大在后),那
// 当前这个排列就是最小的了,如果不是升序,我们要把它弄升序了,这时候排列就是
// 最小的了。
// 如果这个原排列本身全是升序,根据题意,我们直接把它逆序了。
//
// 从nums倒叙遍历两个数nums[i]和nums[i + 1],如果出现升序,则i停止遍历,
// 此时最末位两个升序元素就是nums[i]和nums[i + 1]。
// 在保证i不小于0之后,倒叙遍历nums寻找右半部分比nums[i]大的数nums[j],
// 找到之后,交换nums[i]与nums[j],然后将i右半部的顺序反转。
//
// 执行用时:1 ms, 在所有 Java 提交中击败了98.30%的用户
// 内存消耗:38.8 M, 在所有 Java 提交中击败了10.99%的用户
class Solution {
public void nextPermutation(int[] nums) {
int len = nums.length
int i = len - 2
while (i >= 0 && nums[i] >= nums[i + 1])
i--
if (i >= 0) {
int j = len - 1
while (j >= 0 && nums[i] >= nums[j]) {
j--
}
swap(nums, i, j)
}
reverse(nums, i + 1, len - 1)
}
private void swap(int[] arr, int i , int j) {
int temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
private void reverse(int[] arr, int i, int j) {
while (i < j) {
swap(arr, i++, j--)
}
}
}