题目:
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须 原地 修改,只允许使用额外常数空间。
示例:
输入:nums = [1,2,3]
输出:[1,3,2]
思路:
字典序中下一个更大的排列,首先,字典序就是保持左边不变,右边由正序逐渐变为逆序的过程,最后整体逆序,变得最慢的逆序过来。
比如数组是[1,2,3],其字典序的排列是123,132,213,231,312,321。
数组是[1,2,3,4],字典序排列是
1234,1243,1324,1342,1423,1432
2134,2143,2314,2341,2413,2431
3124,3142,3214,3241,3412,3421
4123,4132,4213,4231,4312,4321
执行过程是:
从右到左遍历到第一个左临小于右临的数,得到其索引为i。
然后从右到左找到第一个大于a[i]的数,得到索引j。
交换两个索引对应的数。
将i右面的部分排列为正序。
代码解析:
从右向左遍历找到第一个左边小于右边的数,返回其索引,如果没有,对原数组逆序,然后从右往左遍历,在i之后的范围内找第一个大于索引i的数,交换这两个数,最后设置左右两个指针,将i右边的数调整为正序。
class Solution(object):
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
#字典序,保持数组左边不变,右边由正序到逆序的过程
down = None
for i in range(len(nums)-2,-1,-1):
if nums[i] < nums[i + 1]:
down = i
break
if down == None:
nums.reverse()
else:
for j in range(len(nums)-1,down,-1):
if nums[j] > nums[i]:
nums[i],nums[j] = nums[j],nums[i]
break
l = i + 1
r = len(nums) - 1
while l < r:
nums[l],nums[r] = nums[r],nums[l]
l += 1
r -= 1