• LeetCode 第31题 下一个排列


    (一)题目描述

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

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

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

      以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
      1,2,3 → 1,3,2
      3,2,1 → 1,2,3
      1,1,5 → 1,5,1

      


    (二)算法思路

      首先解释一下什么是字典序:

      设P是1~n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn
      1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pi<pi+1}
      2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即 k=max{i|pi>pj}(右边的数从右至左是递增的,因此k是所有大于pj的数字中序号最大者)
      3)对换pj,pk
      4)再将pj+1......pk-1pkpk+1......pn倒转得到排列p'=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个排列。
     
      解法:
      解法一:我们可以把所有的排序全部列出来,然后找到下一排列,但是这样的算法效率太低,LeetCode肯定不能通过.但是这也是最简单和最容易想到的方法了.
     
      解法二:一遍扫描法
    1. 我们直接从后往前扫描,先把最后一位当做基准,
    2. 看倒数第二位比倒数第一位大还是小,如果比倒数第一位大,呢就把倒数二位当做基准,直到找到比它小的一位数,我们将其记为 a.
    3. 然后用这位数去和它之后的数进行比较,找到比它大的数中最小的一位b.
    4. 然后交换a和b的位置
    5. 再将a之后的数字逆序排列,就是最终的结果.

       我觉得自己已经解释的很清楚了,但是为了大家更好的去理解这个过程,下面请看一张动图,就能更加清晰的掌握这个过程了.(图是借鉴领扣的)

      Next Permutation


    (三)LeetCode   AC代码

      

     1 public 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, j = nums.length - 1;
    19         while (i < j) {
    20             swap(nums, i, j);
    21             i++;
    22             j--;
    23         }
    24     }
    25 
    26     private void swap(int[] nums, int i, int j) {
    27         int temp = nums[i];
    28         nums[i] = nums[j];
    29         nums[j] = temp;
    30     }
    31 }

     虽然不是很难,但是自己还是搞了很久.

       自己将其总结下来,相信慢慢的自己会有思路去写算法.


         

     

  • 相关阅读:
    蛙蛙推荐:简单介绍一下托管容器持久性(CMP),顺便征集一下.NET CMP2.0的改进方案
    15分钟内快速构建数据访问层(翻译)
    【蛙蛙推荐】.NET 2.0里使用强类型数据创建多层应用
    蛙蛙推荐:迎接web2.0:写一个RSS.HTC组件
    蛙蛙推荐:web下的授权简单解决方案
    J2me访问c# Web Services
    2006年3月份技术随笔
    声讨vs.net,讨论用户控件,编码等问题
    Hadoop中mapred包和mapreduce包的区别
    hbase MapReduce程序样例入门
  • 原文地址:https://www.cnblogs.com/misscai/p/9942497.html
Copyright © 2020-2023  润新知