leetcode--Next Permutation

问题描述

Implement next permutation,which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible,it must rearrange it as the lowest possible order.

The replacement must be in-place,do not allocate extra memory.

Here are some examples,Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

1,2,3->1,3,2

3,2,1->1,2,3

1,1,5->1,5,1

解题思路

首先,关于什么是全排列不做解释。如果一个排列为A,下一个排列为A_next,那么A_next 一定与A有尽可能多的公共前缀。看具体例子,一个排列为124653,如何找到它的下一个排列,因为下一个排列一定与124653有尽可能多的公共前缀,所以,从后面往前看这个序列,如果后面的若干个数字有下一个排列,问题就得到了解决。

第一步:找最后一个数字的下一个全排列。

124653,最后一个数字不具有下一个全排列。

第二步:找最后两个数字的下一个全排列。

124653,最后两个数字是53,不具有下一个全排列。

第三步:找最后三个数字的全排列。

124653,最后三个数字是653,不具有下一个全排列。

第四步:找最后四个数字的下一个全排列。

124653,最后四个数字是4653,它有下一个全排列。

总结上面的操作,有两种终止情况:

1.从后往前比较相邻的两个元素,直到前一个元素小于后一个元素,停止。

2. 如果已经没有了前一个元素,则说明这个排列是递减的,所以这个排列没有下一个全排列。

124653这个排列的终止情况是上面介绍的第一种,从后向前比较相邻的2个元素,遇到4<6的情况就停止。

并且我们可以知道:

1:124653和它的下一个全排列的公共前缀是12(因为4653存在下一个排列,所以前面的数字12保持不变)

2:4后面的元素是递减的(上面介绍的终止条件是前一个元素小于后一个元素,这里是4<6)

现在,我们开始考虑如何找到4653的下一个排列,首先明确4后面的几个数字中至少有一个大于4。

4肯定要和653这3个数字中(6,5)的某一个交换。很明显要和5交换,如何找到这样的元素呢?因为我们知道4后面的元素是递减的,所以653中从后面往前面找,找到第一个大于4的数字,这就是需要和4进行交换的数字。这里我们找到了5,交换之后得到的临时序列为5643,交换后得到的643也是一个递减序列。

所以得到的4653的下一个临时序列为5643,但是既然前面的数字变大了(4653->5643),后面的自然要变为升序才行,变换5643得到5346.所以124653的下一个序列为125346.


算法过程:

在当前序列中,从尾端往前寻找两个相邻元素,前一个记为k,后一个为k+1,满足nums[k]nums[k].然后将第k个元素和第j个元素对调,并将k+1之后的所有元素颠倒顺序,即求出下一个序列。

你可能感兴趣的:(c++,leetcode)