Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such an arrangement is not possible, it must rearrange it as the lowest possible order (i.e., sorted in ascending order).
The replacement must be in place and use only constant extra memory.
Example 1:
Input: nums = [1,2,3]
Output: [1,3,2]
Example 2:
Input: nums = [3,2,1]
Output: [1,2,3]
Example 3:
Input: nums = [1,1,5]
Output: [1,5,1]
Example 4:
Input: nums = [1]
Output: [1]
Constraints:
-
1 <= nums.length <= 100
-
0 <= nums[i] <= 100
下一个排列。
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-permutation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
如果本身已经是降序的了,比如 [3, 2, 1],则返回 [1, 2, 3]。跑一个比较长的例子吧,比如 [1, 5, 8, 4, 7, 6, 5, 3, 1],它的下一个排列是 [1, 5, 8, 5, 1, 3, 4, 6, 7]。因为 input 本身就是 permutation 的一种,又是按字典序,所以发现 4 后面的五个数字是降序的(7, 6, 5, 3, 1);他的下一个排列是需要找到最小的比 4 大的数(5)并且将 4 后面的所有的数字 reverse 成升序。有了这个思路,所以一开始数组需要用一个 i 指针从右往左扫,找到第一个不是升序的数字(4),停下;再用第二个指针 j 从右往左扫第二次,此时找的是第一个比 4 大的数字,会停在 5 的位置;将 4 跟 5 调换一下位置;
[1, 5, 8, 4, 7, 6, 5, 3, 1] -> [1, 5, 8, 5, 7, 6, 4, 3, 1]
最后再反转后五个数字,从而得到下一个排列。
[1, 5, 8, 5, 7, 6, 4, 3, 1] -> [1, 5, 8, 5, 1, 3, 4, 6, 7]
类似题目还有556题。
时间O(n)
空间O(1) - 因为创建的数组最多只有32位,并不随着input变大
JavaScript实现
1 /**
2 * @param {number[]} nums
3 * @return {void} Do not return anything, modify nums in-place instead.
4 */
5 var nextPermutation = function (nums) {
6 let i = nums.length - 2;
7 while (i >= 0 && nums[i] >= nums[i + 1]) {
8 i--;
9 }
10 if (i >= 0) {
11 let j = nums.length - 1;
12 while (j >= 0 && nums[j] <= nums[i]) {
13 j--;
14 }
15 swap(nums, i, j);
16 }
17 reverse(nums, i + 1);
18 };
19
20 var reverse = function (nums, start) {
21 let i = start;
22 let j = nums.length - 1;
23 while (i < j) {
24 swap(nums, i, j);
25 i++;
26 j--;
27 }
28 };
29
30 var swap = function (nums, i, j) {
31 let temp = nums[i];
32 nums[i] = nums[j];
33 nums[j] = temp;
34 };
Java实现
1 class Solution {
2 public void nextPermutation(int[] nums) {
3 int i = nums.length - 2;
4 while (i >= 0 && nums[i + 1] <= nums[i]) {
5 i--;
6 }
7 if (i >= 0) {
8 int j = nums.length - 1;
9 while (j >= 0 && nums[j] <= nums[i]) {
10 j--;
11 }
12 swap(nums, i, j);
13 }
14 reverse(nums, i + 1);
15 }
16
17 private void reverse(int[] nums, int start) {
18 int i = start;
19 int j = nums.length - 1;
20 while (i < j) {
21 swap(nums, i, j);
22 i++;
23 j--;
24 }
25 }
26
27 private void swap(int[] nums, int i, int j) {
28 int temp = nums[i];
29 nums[i] = nums[j];
30 nums[j] = temp;
31 }
32 }
相关题目
31. Next Permutation
556. Next Greater Element III
LeetCode 题目总结