Next Permutation
Posted summerkiki
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Next Permutation相关的知识,希望对你有一定的参考价值。
题目要求:从当前排列生成字典序刚好比它大的下一个排列
思路:
1. 如果一个数右边有比它大的数,那么它就能增大。又因为要寻找刚好比当前值大的下一个排列,所以要先寻找最后一个能增大的数A,其位置为i(位置最低)
2. 使A增大为它右边比它大的最小的数B,交换A和B(如果A右边有多个B,则取位置最低的B)
3. 翻转i后面的数字,使其成增序排列
4. 如果没有找到可以增大的数字,说明当前值已为所有排列的最大值,即一个降序排列,因此按照题目要求直接进行翻转即可
代码如下:
class Solution { public: void reverse(vector<int>& nums, int l, int r) { while(l<r) { int temp=nums[l]; nums[l++]=nums[r]; nums[r--]=temp; } } void nextPermutation(vector<int>& nums) { int place=-1; for(int i=0;i<nums.size()-1;i++) { if(nums[i]<nums[i+1]) place=i; } if(place==-1) reverse(nums,0,nums.size()-1); else { int i=place+1; int large=place+1; while(i<nums.size()-1) { if(nums[i+1]<=nums[i]&&nums[i+1]>nums[place]) //注意此处条件为小于等于 large=i+1; i++; } int temp=nums[place]; nums[place]=nums[large]; nums[large]=temp; reverse(nums,place+1,nums.size()-1); } } };
由于第一步和第二步都是找位置最低的数,所以更好的方式是从后往前寻找,更新代码如下:
class Solution { public: void reverse(vector<int>& nums, int l, int r) { while(l<r) { int temp=nums[l]; nums[l++]=nums[r]; nums[r--]=temp; } } void nextPermutation(vector<int>& nums) { int place=nums.size()-2; while(place>=0 && nums[place]>=nums[place+1]) place--; if(place<0) reverse(nums,0,nums.size()-1); else { int large=nums.size()-1; while(nums[place]>=nums[large]) large--; int temp=nums[place]; nums[place]=nums[large]; nums[large]=temp; reverse(nums,place+1,nums.size()-1); } } };
以上是关于Next Permutation的主要内容,如果未能解决你的问题,请参考以下文章
next_permutation 与 prev_permutation(全排列算法)
LeetCode 31 Next Permutation(下一个全排列)