Next Permutation
Implement next permutation, which rearranges numbers into the lexicographical next greater permutation. If such arrangement is not possible, it must be rearranged as the lowest possible order (i.e., sorted in ascending order). The replacement must be in-place and use constant extra memory.
- 1 <= nums.length <= 100
- 0 <= nums[i] <= 100
nums = [1,2,3][1,3,2]nums = [3,2,1][1,2,3]nums = [1,1,5][1,5,1]Finding the next permutation is like finding the "next largest" number you can build using a specific set of digits. To keep the increase as small as possible, we want to modify the number as far to the right as possible, shifting the smallest "weight" digits first.
The most naive approach is to generate every single permutation of the numbers, sort them lexicographically, find the current arrangement, and return the one immediately after it. Since there are N! permutations, this becomes impossible for even small arrays (e.g., 10! is over 3 million).
# Theoretical approach:
all_perms = sorted(generate_all_permutations(nums))
current_idx = all_perms.find(nums)
return all_perms[current_idx + 1]To make the change as small as possible, we look for the first opportunity (starting from the right) where a smaller digit can be swapped with a larger one.
- If a sequence is decreasing (e.g., [7, 5, 4, 1]), it is already at its maximum possible value. No swap within this group can make it larger.
- We must find the first "dip" from the right — the point where nums[i] < nums[i+1]. This digit is our Pivot.
We can find the next permutation in three precise steps:
1. Find Pivot (i): Scan from right to left. Stop at the first index where nums[i] < nums[i+1].
2. Find Successor (j): If a pivot exists, scan from right to left again to find the smallest number that is still strictly larger than nums[i]. Swap them.
3. Reverse Tail: The numbers to the right of the pivot are currently in decreasing order. Reverse them to make them as small as possible (increasing order).
# 1. Find the first dip from the right
i = len(nums) - 2
while i >= 0 and nums[i] >= nums[i+1]:
i -= 1
if i >= 0:
# 2. Swap pivot with the smallest larger number to its right
j = len(nums) - 1
while nums[j] <= nums[i]:
j -= 1
nums[i], nums[j] = nums[j], nums[i]
# 3. Reverse the descending tail to make it as small as possible
nums[i+1:] = nums[i+1:][::-1]Next Permutation Logic
LEXICOGRAPHICAL RULE
We find the rightmost pivot point that can be increased, swap it with its smallest larger successor, and set the rest to the smallest order (reverse).
THE MAX CASE
If no pivot is found (descending order), we are at the absolute last permutation. We reverse the entire array to wrap back to the first.