题目
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
题目分析
1、字典序含义
在数学中,字典或词典顺序(也称为词汇顺序,字典顺序,字母顺序或词典顺序)是基于字母顺序排列的单词按字母顺序排列的方法。 这种泛化主要在于定义有序完全有序集合(通常称为字母表)的元素的序列(通常称为计算机科学中的单词)的总顺序。
对于数字1、2、3…n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列 12354和12345,排列12345在前,排列12354在后。按照这样的规定,5个数字的所有的排列中最前面的是12345,最后面的是 54321。
按照题目要求,需要输出该序列的下一个排列,例如输入 nums={1,3,2,4,5} ,则应输出下一个排列 {1, 3, 2, 5, 4} 。
2、原地修改且额外空间为常数
题目中要求原地修改,因此我们尽量只对原数组进行操作;
额外空间为常数,则我们不能另外建立空间为n的辅助数组来进行计算;
3、如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)
若当前数组为字典中最大值,则其下一个数组为字典中最小值。
代码设计
1、代码初步构想
若我们抛开题目来看,对于任意一串数字,它的后一位数字都是修改其最小项,使其+1得到的,例如:
数字 542
若求它的后一位数字,只需要在其个位数上+1即可得到该数字的后一位数字 543
因此,该题的求解应该从数组尾部开始入手。
2、代码整体框架
我们可以定义一个切割点 index 从尾部往前分割数组,对于分割下来的数组进行判断,使得其 字典序
往后一位,此时,数组整体的 字典序 也就往后排了一位。因此,数组整体的下一个排序问题,被修正成了切割数组的下一个排列问题。
3、进一步讨论
如同上面所说的,数字 542 的下一个数是 543 一样,当我们要寻找一个数组的下一个字典序时,会发现如下现象:
假设当前数组 nums = {2, 3, 5, 8, 7} ,其下一个字典序应该是 {2, 3, 7, 5, 8} ,按照上述算法从后往前进行拆分,会有如下现象:
①切割数组: {7}
此时仅有一个数字,继续切割;
①切割数组: {8, 7}
此时,该序列为倒序序列,不存在下一个字典数,继续切割;
①切割数组: {5, 8, 7}
此时,该序列不为倒序序列,存在下一个字典序,因此寻找该序列的下一个字典序。我们很容易找到比5大的下一个数字是7ÿ