31. 下一个排列(中等)
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数)。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须 原地 修改,只允许使用额外常数空间。
示例 1:
输入:nums = [1,2,3]
输出:[1,3,2]
示例 2:
输入:nums = [3,2,1]
输出:[1,2,3]
示例 3:
输入:nums = [1,1,5]
输出:[1,5,1]
示例 4:
输入:nums = [1]
输出:[1]
提示:
- 1 <= nums.length <= 100
- 0 <= nums[i] <= 100
思路
最重要的是弄清楚什么是下一个排列?这个排列“递增”的规律是什么?
排列组合的顺序是自小到达逐渐演变的;例如:对于5个数字的排列12354和12345,排列12345在前,排列12354在后。按照这样的规定,5个数字的所有的排列中最前面的是12345,最后面的是54321。
全排列的算法如下:
设A是1~n的一个全排列:A=a1a2…an。
1)从排列的最右端开始,找出第一个比右边数字小的数字(即 a[i] < a[i+1]
)的序号i(i为数组下标);
2)在a[i]的右边的所有数字中(即[i + 1, n]
中),从右到左找出第一个比a[i]大的数
的序号j;(因为右边的数从右至左是递增的) ;
3)对换a[i]和a[j]
4)再将a[j + 1] … a[n]反转,这就是下一个排列
。
这题更像是一个数学题,知道排列的规律很好处理,但是…
代码
复杂度分析
- 时间复杂度:O(N),其中N 为数组长度。我们至多只需要扫描两次序列、进行一次反转操作。
- 空间复杂度:O(1),存放诸如n、left等变量