题目描述
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
解题思路
这个题目没有考到什么算法,应该是考察对于vector的使用以及对题目的思考吧。只要把题目读懂,并且想清楚了,这道题目就很好做。题目我是理解了很久才懂它的意思,其实简单来讲,以题目给的1,2,3这个例子为例,我们要得到的是由1,2,3这三个数字组成的三位数中,比123大的下一个三位数,自然就是132.因为其他几个排列213,231,312,321都比132要大。所以自己在纸上写几个例子,就会发现一个规律,我们从nums[1]开始,一直判断nums[2],nums[3],从而可以找到这样一个转折点index,在这个转折的数字的右侧所有数字都是递减(左侧未必都递增)。在例子1,1,5中这个转折点就是nums[1]也就是1.此时我们只要找到index右侧比index位置的值大的最小数字next,就可以进行index和next数字的交换,并且对于index+1到nums.size()-1的所有数字进行递增排序,就可以最终得到我们要求的下一个排列。
刚开始我第一次提交的时候有几十个样例没有通过,因为我刚开始是直接交换index和index+1这两个数字,没有考虑到index+1之后可能还存在比index+1的数字小,并且比index的数字大的值。我们要找的是下一个排列,自然就应该找到index右侧比index位置的值大的最小数字进行交换,才能保证是下一个排列。这里修改了一下,就通过了所有的样例。
通过的代码
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int index=nums.size()-1;
int next;
int mid;
for(int i=nums.size()-2;i>=0;i--)
{
if(nums[i]<nums[i+1])
{
index=i;
break;
}
}
if(index==(nums.size()-1))
sort(nums.begin(),nums.end());
else
{
next=index+1;
while((next+1)<nums.size()&&nums[next+1]>nums[index])
next++;
mid=nums[index];
nums[index]=nums[next];
nums[next]=mid;
sort(nums.begin()+index+1,nums.end());
}
}
};