c/c++语言开发共享#leetcode刷题之路31-下一个排列

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。必须原地修改,只允许使用额外常数空间。 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。1,2,3 → 1,3,23,2,1 → 1,2, …

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

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
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;  }

 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/604687.html

(0)
上一篇 2021年5月12日
下一篇 2021年5月12日

精彩推荐