[LeetCode] 31. Next Permutation

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

下一个排列。

整数数组的一个 排列  就是将其所有成员以序列或线性顺序排列。

例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。
整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。
类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。
而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。
给你一个整数数组 nums ,找出 nums 的下一个排列。

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/next-permutation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

如果 input 本身已经是降序的了,比如 [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) - input数字的长度

空间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 题目总结

posted @ 2020-03-05 08:39  CNoodle  阅读(426)  评论(0编辑  收藏  举报