zoukankan      html  css  js  c++  java
  • #leetcode刷题之路31-下一个排列

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

    以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
    1,2,3 → 1,3,2
    3,2,1 → 1,2,3
    1,1,5 → 1,5,1

    思路:1.尝试一次遍历就解决问题。从后向前遍历数组,如果后一个总是比前一个大,那么排列就是最大的,这时需要反转排列。

    2.如果在遍历过程中发现了一个比之前一个小的数,位置为i(此时i后面的数以降序排列,是最大值),此时反过来向后遍历,找到后面部分中最后一个比这个数大的数,交换两数(此时位置i后面的数降序排列,不过比之前的小),这时,i后面的数依然以降序排列,是最大值,但是我们想要得到的是下一个更大的排列,因此我们需要把i后面的数反序。即:小+最大排列-->大+最小排列

    #include <iostream>
    #include <vector>
    
    using  namespace std;
    
    void reverse(int begin,int end,vector<int>& nums)//用于反转序列
    {
        while(begin<end)
        {
            int temp=nums[begin];
            nums[begin]=nums[end];
            nums[end]=temp;
            begin++;
            end--;
        }
    }
    
    
    void nextPermutation(vector<int>& nums) {
        int i;
        int len=nums.size();
        if(len==0||len==1) return;
        if(len==2) {reverse(0,1,nums);
            return;}
        for(i=len-2;i>=0;i--)
        {
            if(nums[i]>=nums[i+1]) continue;
            else break;
        }
        if(i==-1) reverse(0,len-1,nums);
            //i记录要交换的位置
        else
        {
            for(int j=len-1;j>=i+1;j--)
            {
                if(nums[j]>nums[i])
                {
                    int t=nums[j];
                    nums[j]=nums[i];
                    nums[i]=t;
                    reverse(i+1,len-1,nums);
                    break;
                }
            }
        }
    }
    
    int main() {
        vector<int> a={1,3,2};
        nextPermutation(a);
        std::cout <<a[0] <<a[1]<<a[2]<< std::endl;
        return 0;
    }
  • 相关阅读:
    广域网详解
    无线AP和无线路由器区别
    TRUNK的作用功能.什么是TRUNK
    name after, name for, name as
    让你的情商爆棚吧!
    综合布线系统之7个子系统构成
    网桥和交换机的工作原理及区别
    边界网关协议BGP
    OSPF协议详解
    路由信息协议(RIP)的防环机制
  • 原文地址:https://www.cnblogs.com/biat/p/10563877.html
Copyright © 2011-2022 走看看