Leetcode刷题记录--31. 下一个排列

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

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

这一题总体还是比较简单的,但是重在思路,一开始我只能想出来如果要找一个最大的数,假如数字序列中存在一个x,那肯定要用一个在x对应的索引之后,比x稍大的数替换这个x,但是我却不能找到应该替换哪一个数字,后来看了题解豁然开朗,其实就差一点点。

  • 让我们先思考一下最极端的情况,也就是整个序列组成的数字是最大的,比如说7654321,那么这个数字序列有什么规律呢,没错它是逆序的,所以说要想达到最大或者部分区域最大,这个区域的数字序列一定是逆序的,那有了这个想法就好理解了。
  • 我们先从序列的后面向前找,找到第一个破坏逆序的情况:nums[i-1]<nums[i],我们把index=i-1,那么index之后的序列一定是逆序的,也就是区域最大了。
  • 此时我们可以在index对应的数字右边找到一个数字比nums[index]稍大的进行替换,比如说1235476,其中76是逆序的保证区域最大,而47是从后到前第一个非逆序的序列,因此我们可以取4右边的6替换,得到1235674
  • 但此时还没有结束,记得我们提到的区域最小区域最大的概念么,让我们观察此时得到的结果1235674,其中从12356已经比原来的左部12354大了,我们如果不做任何处理,很有可能导致得到的结果不是原数的下一个序列,而是下下下个,所以我们将index右边的数升序,保证区域最小,得到1235647。

Leetcode题解中还用到了图示,刚刚的用例1235476得到的图解就是下面的模样,哈哈是不是有种海浪上下翻滚的感觉!


或者这么表示似乎更贴切

猜你喜欢

转载自www.cnblogs.com/yuyuan-bb/p/12766288.html