class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
# main idea is to (1) find a larger number than current nums (2) increment between next bigger and current number is as small as possible ==> start from lower digit/ least significant digit
# time O(N) space O(1)
size = len(nums)
# step0, start from last one, looping towards head of nums
for i in range(size-1,0,-1):
cur = nums[i]
pre = nums[i-1]
# step1 find the smallest number on the right that's lager than pre
if cur > pre:
idx = i
_min = cur
for k in range(i+1,size):
if nums[k] > pre and nums[k] <= _min: # note, if using <, for arr[i:] where there are equal numbers at the end will not be sorted by using swap method
idx = k
_min = nums[k]
#step2, swap pre with _min
nums[i-1] = _min
nums[idx] = pre
#step3: sort arr start from curr or nums[i] in ascending order
n = size - i
for k in range(n//2):
nums[i+k],nums[i+n-k-1] =nums[i+n-k-1] ,nums[i+k]
return
#step4 there is not next bigger number(current one is biggest), so reverse it to convert into smallest
for i in range(size//2):
nums[i],nums[size-1-i] = nums[size-1-i],nums[i]