Algorithm

Next Permutation

Arrays & Strings Pattern

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.

CONSTRAINTS
  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100
EXAMPLE 1
Input: nums = [1,2,3]
Output: [1,3,2]
Pivot is 2 (since 2 < 3). Swap with 3, reverse the (single-element) tail. [1,3,2] is the very next arrangement after [1,2,3].
EXAMPLE 2
Input: nums = [3,2,1]
Output: [1,2,3]
Fully descending — already the largest arrangement. No pivot exists, so we wrap around by reversing everything to the smallest.
EXAMPLE 3
Input: nums = [1,1,5]
Output: [1,5,1]
Duplicates are fine: pivot is the second 1 (1 < 5), swap with 5, reverse the tail.
What does 'lexicographically next' mean exactly?
Line up all rearrangements in dictionary order (compare element by element from the left). Return the one immediately after the current arrangement — the smallest rearrangement strictly greater than it.
What if the array is entirely decreasing?
Then it is already the largest possible arrangement. The problem defines the answer as wrapping to the smallest — i.e. reverse the array into ascending order.
How do duplicates affect the algorithm?
They are handled by two strictness choices: the pivot scan skips equal neighbors (nums[i] >= nums[i+1] keeps moving), and the successor must be strictly greater than the pivot. Both are needed to avoid swapping equal values and producing the same permutation.
Do I return a new array?
No — modify nums in place with O(1) extra memory. There is no return value.

Two definitions first, because the whole problem lives inside them. A permutation of an array is a rearrangement of exactly the same elements — same multiset, different order. Lexicographic order is dictionary order applied to sequences: compare position by position from the left, and the first position where they differ decides which is smaller — precisely how "apple" comes before "apply". Under this ordering, all rearrangements of the array line up from smallest ([1,2,3]-style, ascending) to largest (descending). Our task: given one arrangement, produce the one immediately after it in that lineup — the smallest rearrangement that is strictly greater. If the input is already the largest, wrap around to the smallest. And do it in-place with constant extra memory.

The unusable brute force

Generate every permutation, sort them, find ours, return the next one. There are N! arrangements — 10 elements give 3.6 million, 15 give over a trillion. Dead on arrival, but it defines what "next" means:

python
# Theoretical only:
all_perms = sorted(generate_all_permutations(nums))
current_idx = all_perms.find(nums)
return all_perms[current_idx + 1]
Think like a car odometer

How do you increase a sequence by the least possible amount? The same way counting works: change it as far to the right as you can, because under dictionary order the left positions dominate — any change at position i outweighs everything after it, so the earliest (leftmost) changed position should be as far right as possible.

So scan from the right asking: "can the suffix starting here be rearranged into something strictly larger?" Here is the key fact: a suffix that is non-increasing (each element ≥ the next, like [7, 4, 3, 1]) is already the largest possible arrangement of its own elements — rearranging a descending stack can only move a smaller element earlier, which makes it smaller. Such a suffix has no "next"; keep moving left. The scan stops at the first index i where nums[i] < nums[i+1] — the first place, from the right, where improvement is possible. Call it the pivot. If no such index exists, the entire array is descending: it is the global maximum, and per the problem's rule we reverse the whole thing to wrap to the global minimum.

The smallest legal step

At the pivot, the increase is unavoidable — so make it minimal, twice over. First: the new value at the pivot position should be the smallest element to its right that is still strictly greater than the pivot. The suffix is descending, so scanning from the far right, the first element greater than the pivot is exactly that one. Swap them. Second: everything after the pivot should now be as small as possible — and the smallest arrangement of any elements is ascending order. Conveniently, the suffix is still descending after the swap (the swapped-in value sits exactly where an equal-or-larger value sat, so the ordering holds), which means "sort ascending" is just "reverse" — O(N), no actual sorting.

python
# 1. Find the pivot: first index from the right with nums[i] < nums[i+1]
i = len(nums) - 2
while i >= 0 and nums[i] >= nums[i+1]:
    i -= 1

if i >= 0:
    # 2. Swap pivot with the smallest element to its right that beats it
    j = len(nums) - 1
    while nums[j] <= nums[i]:
        j -= 1
    nums[i], nums[j] = nums[j], nums[i]

# 3. The tail is descending; reverse it to make it the minimum
nums[i+1:] = nums[i+1:][::-1]
Worked Example:nums = [1, 2, 7, 4, 3, 1]
- Find pivot: from the right, 1, 3, 4, 7 climb steadily — that suffix is maxed out. At index 1 we hit 2 < 7. Pivot = 2 (index 1).
- Find successor: rightmost element greater than 2 in the tail [7, 4, 3, 1] is 3. Swap: [1, 3, 7, 4, 2, 1].
- Reverse the tail after the pivot: [7, 4, 2, 1] becomes [1, 2, 4, 7].
- Answer: [1, 3, 1, 2, 4, 7] — the smallest arrangement that begins with the forced increase 1, 3.
Why this matters beyond the puzzle

Three scans, each at most N steps: O(N) time, O(1) space, in place. The transferable skeleton is the enumeration principle itself: to step to the "next" item in any ordered listing, change the least significant thing you legally can, then minimize everything after the change. That exact skeleton generates combinations, k-th permutations, and appears whenever a problem says "next greater arrangement". And the little lemma you proved on the way — "a descending run is the maximum arrangement of its elements" — is the reusable insight that makes the pivot scan work.

Interactive Strategy Visualization

Next Permutation Logic

Lexicographical Shift Strategy
1
2
7
4
3
1
Starting: Find the next bigger sequence version of [1, 2, 7, 4, 3, 1].
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.

O(N!) Generate All
O(N) Pivot-Swap-Reverse