class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
i = len(nums) - 2
#找到一个较小的数
while i >= 0 and nums[i] >= nums[i + 1]:
i -= 1
#如果找到了那就从最后面的位置在开始找比较小数大的一个数
if i >= 0:
j = len(nums) - 1
while j >= 0 and nums[i] >= nums[j]:
j -= 1
#找到较大数以后交换两个位置
nums[i], nums[j] = nums[j], nums[i]
#从交换后到最后一个元素重新进行从小到大的排序
#执行这一步骤的原因是要找到下一个更大的排序,而不是比它大的排序,重要的是下一个排序
left, right = i + 1, len(nums) - 1
while left < right:
nums[left], nums[right] = nums[right], nums[left]
left += 1
right -= 1
这个题目其实有坑,要找的是下一个更大的排序而不是更大的排序,因此关键的问题就在于是下一个排列。
- 从后往前找,找到一个小于后一个元素的较小元素小标index1
- 如果没有找到较小位置的元素,那就说明本身已经是最大了,所以将原数组从小打到进行排序
- 如果找到较小位置元素,然后再从后往前找,找一个大于较小元素的数index2,那就将较大的数和较小的数交换位置
- 然后从较大的那个数之后的元素需要重新进行递增的排序
- 完成找到下一个更大的排序任务
总结:
- 为啥从最后面开始找?
- 因为要找下一个较大的排序,所有肯定从后面找,可以保证找到较大的;如果从前开始找只能找到最大的排序
- 为啥交换完还要对后面的元素进行排序?
- 因为找的是下一个较大排序,因此交换完之后要保证较大元素后面的排序应该是最小的
- 举个简单的例子
- 12543
- 交换:13542:这个当然不是下一个较小的排序
- 排序:13542->13245
- 结果:最终的结果是13245