• [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

    下一个排列。

    实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

    如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

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

    来源:力扣(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 题目总结

  • 相关阅读:
    结对编程2
    结对编程总结:简单的四则运算生成程序
    我的结对项目心得与代码规范
    一个团队和他们的调查表-----("调查表与调查结果分析"心得体会)
    目标?我定好了!(我的软件工程课目标)
    Jmeter响应数据为乱码的处理
    软件工程课程建议
    结对编程之Fault、Error、Failure
    我的结对项目编程感想
    调查问卷后的心得
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12418303.html
Copyright © 2020-2023  润新知