我猜测应该有不少人没能理解这道题到底在干什么?
一开始我一没看懂,网上的一些文章也没有说的很明白,后来参考了这个,才算搞明白!
题目给定了数组的一个排列,求下一个排列是什么?
基本的思路是
- 从最后面开始找第一个开始递减的数,记录较小的数的位置p;
- 如果p存在,从p开始,依次向后找到第一个比p位置的数小的数,记录这个数的前一个位置为q,交换p,q位置上的数,并将p位置后的所有数逆置
- 如果p不存在,即p<0,直接将整个数组逆置即可。
按照这个流程写的代码:
class Solution:
def nextPermutation(self, nums: 'List[int]') -> 'None':
"""
Do not return anything, modify nums in-place instead.
"""
p = len(nums) - 1
pre = p - 1
while pre >= 0:
if nums[pre] >= nums[p]:
pre -= 1
p -= 1
else:
break
if pre == -1:
l, r = 0, len(nums) - 1
while l <= r:
nums[l], nums[r] = nums[r], nums[l]
l += 1
r -= 1
return
q = p
p = pre
while q < len(nums) and nums[q] > nums[pre]:
q += 1
q -= 1
nums[p], nums[q] = nums[q], nums[p]
i, j = p + 1, len(nums) - 1
while i <= j:
temp = nums[i]
nums[i] = nums[j]
nums[j] = temp
i += 1
j -= 1
不得不说,上面的代码实在啰嗦,实际上可以将两种情况综合一下
class Solution(object):
def nextPermutation(self, nums):
if not nums: return None
i = len(nums)-1
j = -1 # j is set to -1 for case `4321`, so need to reverse all in following step
while i > 0:
if nums[i-1] < nums[i]: # first one violates the trend
j = i-1
break
i-=1
for i in xrange(len(nums)-1, -1, -1):
if nums[i] > nums[j]: #
nums[i], nums[j] = nums[j], nums[i] # swap position
nums[j+1:] = sorted(nums[j+1:]) # sort rest
return