题目:
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
示例:
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
思路:
组合数学恰好学习了查找下一个排列的算法,在此记录一下。
- 从右到左遍历序列,找出第一个右边数字比自身大的数字,记录位置,记为
x
; - 在这个数字的右侧找到最小的大于这个数字的数,记录位置;
- 交换这两个数;
- 位置
x
右侧的数字序列反序,即为下一个排列。
以839647521
为例:
找出第一个右边数字比自身大的数字:4
在这个数字的右侧找到最小的大于这个数字的数:5
交换这两个数:839657421
5右侧的数字序列反序:839651247
即为所求。
代码:
class Solution(object):
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
if not nums:
return nums
aim = 0
for i in range(len(nums)-1, -1, -1):
if (i-1) >= 0:
if nums[i-1] >= nums[i]:
continue
else:
aim = i-1
break
temp = aim+1
while temp < len(nums):
if nums[temp] <= nums[aim]:
break
temp += 1
temp -= 1
if temp == 0:
for i in range(int(len(nums)/2)):
nums[i], nums[len(nums)-1-i] = nums[len(nums)-1-i], nums[i]
return nums
else:
nums[aim], nums[temp] = nums[temp], nums[aim]
length = len(nums) - aim - 1
for i in range(int(length / 2)):
nums[aim + i + 1], nums[len(nums) - i - 1] = nums[len(nums) - i - 1], nums[aim + i + 1]
return nums