• 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%的用户

  • 相关阅读:
    Linux三剑客之sed深度实践讲解(上)
    Linux第三阶段题型测试
    Linux正则表达式题型
    linux文本处理三剑客命令及用法
    SSH服务协议、部署ssh、scp、sftp服务
    NFS客户端挂载及永久生效
    SSH实现无密码登录
    NFS深度解析及搭建同步NFS服务
    NFS文件系统及搭建NFS共享服务
    Linux系统磁盘管理
  • 原文地址:https://www.cnblogs.com/liuyongyu/p/14201094.html
Copyright © 2020-2023  润新知