zoukankan      html  css  js  c++  java
  • Leetcode31.下一个排列

    题目:下一个排列

    思路:找规律。在字典序中,用在字典中出现的次序代表该字符的值,用直接连接字符,那么最小排列的字符串就是单调递增的一条直线。从最小排列开始逐渐增大排列,那么可以发现从直线的末端开始,会不断的出现顶点并向前延伸,直到直线变成了单调递减。可以发现每一次增大的排列都是末端顶点向前移动。为了更好的说明情况,这边引用题解中的一张图。

    图中可以知道,当前的排列是12385764。可以看到图中有两个顶点,分别为8和7,那么可以改变末端顶点附近的字符获得下一个排列。步骤如下:
    • 从尾端向前搜索,直到到达第一个顶点处;(从4向1方向搜索,7这个位置为搜索到的第一个顶点)
    • 那么顶点的前一个字符,就是我们需要被替换的字符,替换的字符是在刚刚搜索中比被替换字符大一点的字符;(5是被替换的字符,7和6都比5大,选其中最小的作为替换字符,这儿选6是替换字符)
    • 替换完后对从顶点位置开始进行升序排列。(替换后的排列是12386754,从顶点7开始排序,即754->457
    • 上述步骤完成后,就得到下一个排列。(12385764->12386457

    代码:

    class Solution {
         public void nextPermutation(int[] nums) {
            int idx = nums.length-1;
            while(idx > 0 && nums[idx] <= nums[idx-1]) --idx;
            if(idx <= 0) {
                reverse(nums);
            }else{
                int i = idx;
                while(i<nums.length && nums[i] > nums[idx-1]) i++;
                int t = nums[idx-1] ^ nums[i-1];
                nums[idx-1] ^= t;
                nums[i-1] ^= t;
                Arrays.sort(nums, idx, nums.length);
            }
        }
        private void reverse(int[] nums){
            for(int l = 0, r = nums.length - 1, t = 0; l < r; l++, r--){
                t = nums[l] ^ nums[r];
                nums[l] ^= t;
                nums[r] ^= t;
            }
        }
    }
    

    执行用时:1 ms, 在所有 Java 提交中击败了96.93%的用户
    内存消耗:38.5 MB, 在所有 Java 提交中击败了79.92%的用户

  • 相关阅读:
    RF手持配置问题
    S4系统编辑屏幕报错
    【SAP】日志表CDHDR和CDPOS
    VA01隐藏销售凭证流的金额
    ABAP MODIFY SCREEN
    解决SMARTFORMS 中table 控件单行跨页的问题
    golang json 性能分析
    【高性能】GO 高性能专题
    9千万次循环 从2分3秒 优化到 7.3秒的过程 GO语言
    IDE 插件开发 相关点 -------------- Vscode debug protocol JDWP DAP
  • 原文地址:https://www.cnblogs.com/liuyongyu/p/14201094.html
Copyright © 2011-2022 走看看