zoukankan      html  css  js  c++  java
  • 【leetcode】31. Next Permutation

    题目说明

    https://leetcode-cn.com/problems/next-permutation/description/
    实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
    如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
    必须原地修改,只允许使用额外常数空间。

    解法1

    找到下一个更大序列,可以理解为将数字序列想像成由这些数字序列组成的一个数字,要找到相同数字组合的下一个更大数字。

    定点

    从序列的右边开始遍历,找到第一个相邻的数字序列[i,i+1]满足i+1的值大于i的值,那么从i到数字序列结尾就需要重新排列了。
    比如说[1,2,3,4,5,6,2,1],第一个满足上述条件的是5与6,需要将5到结尾的序列重新排列。
    这里需要注意的是如果满足上述条件,[i+1,nums.size() -1]区间必定是一个降序序列。

    交换

    首先要找到最近的较大值,我们需要在[i+1,nums.size() -1]的区间找到最小的比nums[i]大的值,然后与nums[i]进行交换。
    由于该区间是降序序列,从后往前遍历第一个比nums[i]大的位置即是我们要找的。
    上述例子[1,2,3,4,5,6,2,1],6是最小的比5大的值,需要与5交换:[1,2,3,4,6,5,2,1]

    反转

    交换以后,得到的序列并不是“下一个”更大的序列,还需要将[i+1,nums.size() -1]进行反转,将较小的数移至高位,才能得到满足条件的序列。
    上述例子,将[1,2,3,4,6,5,1]中的[5,2,1]进行反转,得到序列[1,2,3,4,6,1,2,5],即最终结果。

    特殊地,若找不到第一个相邻的数字序列[i,i+1]满足i+1的值大于i的值,即本身序列是个降序序列,则需要将整个序列整体反转。
    代码如下:

    /*
     * 时间复杂度:O(n)
     */
    void nextPermutation(vector<int>& nums) {
        int tmp = 0;
        int i = 0;
        //找到第一个相邻的数字序列[i,i+1]满足i+1的值大于i的值
        for(i = nums.size() - 2; i >=  0; i --){
            if (nums[i] < nums[i + 1]){
                break;
            }
        }
    
        if (i >= 0){
            int j = 0;
            //从后往前遍历第一个比nums[i]大的位置
            for (j = nums.size() - 1; j >= 0; j --){
                if (nums[j] > nums[i]){
                    break;
                }
            }
            swap(nums, i, j);
        }
        //反转序列
        revert(nums, i + 1);
    
        return;
    }
    
    int swap(vector<int>& nums, int i, int j)
    {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
        return 0;
    }
    
    int revert(vector<int> & nums, int start)
    {
        int i = start;
        int j = nums.size() - 1;
    
        while(i < j){
            swap(nums,i,j);
            i ++;
            j --;
        }
        return 0;
    }
  • 相关阅读:
    zzuli-2259 matrix
    【vlan之四种方式链路认证组网]
    【ppp-chap,pap,mp,mp-group】
    【ospf-基础配置】
    【rip-基础配置】
    【静态路由】
    【nat---basic,napt,easy ip】
    【acl-访问控制列表】
    【交换接口的-绑定-认证-隔离】
    【vlan-给予mac地址认证】
  • 原文地址:https://www.cnblogs.com/JesseTsou/p/9637879.html
Copyright © 2011-2022 走看看