Next Permutation

mediumAmazon-tagged: Arrays & Strings26 stepsJava · Python · C++

Rearrange numbers into the next lexicographically larger permutation, in place. Find the rightmost index i with nums[i] < nums[i+1] (the pivot). Swap it with the smallest larger value to its right, then reverse the suffix after i to make it as small as possible.

▶ Watch the animated trace

Traced input: nums = [1, 3, 5, 4, 2] → [1, 4, 2, 3, 5]. Original problem: neetcode.io/problems/next-permutation

Complexity

BestO(n)
AverageO(n)
WorstO(n)
SpaceO(1)

At most two scans and one reversal.

Key idea

Common mistakes

Solution

Java
void nextPermutation(int[] nums) {
    int i = nums.length - 2;
    while (i >= 0 && nums[i] >= nums[i + 1]) i--;
    if (i >= 0) {
        int j = nums.length - 1;
        while (nums[j] <= nums[i]) j--;
        swap(nums, i, j);
    }
    reverse(nums, i + 1, nums.length - 1);
}

void swap(int[] a, int i, int j) { int t = a[i]; a[i] = a[j]; a[j] = t; }

void reverse(int[] a, int l, int r) { while (l < r) swap(a, l++, r--); }
Python
def nextPermutation(nums: List[int]) -> None:
    i = len(nums) - 2
    while i >= 0 and nums[i] >= nums[i + 1]: i -= 1
    if i >= 0:
        j = len(nums) - 1
        while nums[j] <= nums[i]: j -= 1
        nums[i], nums[j] = nums[j], nums[i]
    nums[i + 1:] = reversed(nums[i + 1:])
C++
void nextPermutation(vector<int>& nums) {
    int i = (int)nums.size() - 2;
    while (i >= 0 && nums[i] >= nums[i + 1]) i--;
    if (i >= 0) {
        int j = (int)nums.size() - 1;
        while (nums[j] <= nums[i]) j--;
        swap(nums[i], nums[j]);
    }
    reverse(nums.begin() + i + 1, nums.end());
}

Edge cases

Each one has its own trace in the interactive view.

CaseInputAnswer
Last permutation wraps
No pivot: reverse everything.
nums = [3, 2, 1][1, 2, 3]
Duplicates
The pivot is 1 at index 0; the next larger is 5.
nums = [1, 5, 1][5, 1, 1]
Single element
Nothing to change.
nums = [1][1]
Simple swap
Pivot at index 1.
nums = [1, 2, 3][1, 3, 2]
← String CompressionSpiral Matrix →