【Leetcode】31.下一个排列
31.下一个排列
题目
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
方法
当给定排列已经是最大排列时,这种情况单独考虑,只需反转数组即可。
否则,下一个排列肯定比当前排列要大,而且要尽可能让变大的幅度很小。
步骤如下:
- 从后向前遍历数组,找到第一个升序位置对 (index,index+1),满足 a[index] < a[index+1]。在index之后的所有位置i,都符合降序。意味着nums[index…]为以index开头的最大排列。既然我们要找一个更大的排列,意味着不能再以index开头,我们要在index位置后面找到一个最小比它大的数代替它。
- 于是我们在index位置右边从后向前寻找第一个比nums[index]大的元素位置j。因为nums[index+1….]为降序排列,因此第一个出现的比nums[index]大的元素就是最小比nums[index]大的元素。
- 之前nums[index…]为以nums[index]开头的最大排列,现在我们要让nums[index…]变为以nums[j]开头的最小排列,于是将index位置和j位置交换,即让一个最小的比nums[index]大的元素nums[j]代替它。
- 再反转nums[index+1…..],让这段区间由降序变成升序。此刻index位置右边为以nums[j]元素开头的最小排列。
1 |
|
- 时间复杂度:O(N)
- 空间复杂度:O(1)