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;
    }
  • 相关阅读:
    hdu 1042 N!
    hdu 1002 A + B Problem II
    c++大数模板
    hdu 1004 Let the Balloon Rise
    hdu 4027 Can you answer these queries?
    poj 2823 Sliding Window
    hdu 3074 Multiply game
    hdu 1394 Minimum Inversion Number
    hdu 5199 Gunner
    九度oj 1521 二叉树的镜像
  • 原文地址:https://www.cnblogs.com/JesseTsou/p/9637879.html
Copyright © 2011-2022 走看看