zoukankan      html  css  js  c++  java
  • Leetcode: Next Permutation

    Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
    
    If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
    
    The replacement must be in-place, do not allocate extra memory.
    
    Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
    1,2,3 → 1,3,2
    3,2,1 → 1,2,3
    1,1,5 → 1,5,1

    这道题的算法第一次可能有点难想,但是做过一次后就知道了

    Shi Li Analysis(会好理解很多):

    Starting from the last position, the first time we find that num[i]<num[i+1], we stop. The position i is the position that will be increased. We need to find out the next large num in num[i+1...len-1] and change num[i] to that number. Suppose it is num[j], then num[i]=num[j]. For the rest part to the array, we arrange them in an increasing order of num[i]...num[len-1] except num[j]. 

    we actually can observe that the part num[i+1]...num[len-1] is actually reversely ordered already. Therefore, all we need to do is find out num[j], and reverse the part num[i]...num[len-1]. The complexity is decreased to O(n).

    用一个例子来说明,比如排列是(2,3,6,5,4,1),求下一个排列的基本步骤是这样:
    1) 先从后往前找到第一个不是依次增长的数,记录下位置p。比如例子中的3,对应的位置是1;
    2) 接下来分两种情况:
        (1) 如果上面的数字都是依次增长的,那么说明这是最后一个排列,下一个就是第一个,其实把所有数字反转过来即可(比如(6,5,4,3,2,1)下一个是(1,2,3,4,5,6));
        (2) 否则,如果p存在,从p开始往后找,找到下一个数就比p对应的数小的数字,然后两个调换位置,比如例子中的4。调换位置后得到(2,4,6,5,3,1)。最后把p之后的所有数字倒序,比如例子中得到(2,4,1,3,5,6), 这个即是要求的下一个排列。

    以上方法中,最坏情况需要扫描数组三次,所以时间复杂度是O(3*n)=O(n),空间复杂度是O(1)。

    至于一些细节5行第二个不等号是>=而不是 >,  第10行第二个不等号是>而不是>=, 推导一下 {2,3,5,5,4,3}这个例子

     1 public class Solution {
     2     public void nextPermutation(int[] num) {
     3         if (num == null || num.length == 0 || num.length == 1) return;
     4         int i = num.length-2;
     5         while (i >= 0) {
     6             if (num[i] < num[i+1]) break;
     7             i--;
     8         }
     9         if (i >= 0) {
    10             int j = i;
    11             while (j < num.length-1) {
    12                 if (num[j+1] <= num[i]) break;
    13                 j++;
    14             }
    15             int temp = num[i];
    16             num[i] = num[j];
    17             num[j] = temp;
    18         }
    19         reverse(num, i+1);
    20     }
    21     
    22     public void reverse(int[] num, int k) {
    23         int start = k;
    24         int end = num.length - 1;
    25         while (start < end) {
    26             int temp = num[start];
    27             num[start] = num[end];
    28             num[end] = temp;
    29             start++;
    30             end--;
    31         }
    32     }
    33 }
  • 相关阅读:
    Object.defineProperty实现数据绑定
    trigger回调方法的实现
    window.print()打印页面指定内容(使用iframe保证原页面不失效)
    Visual Studio Code 快捷键大全(Windows)
    个人博客-逐梦博客,宋
    Vue.js项目在apache服务器部署后,刷新404的问题
    阿里云ECS服务器Ubuntu配置MySQL远程访问
    最全面的css布局
    js中数组常用方法总结
    PHP环境搭建
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/4007905.html
Copyright © 2011-2022 走看看