AlgoVerse

Next permutation

Build the next permutation in dictionary order in place: find the first dip from the end, one swap and one reversal.

Order the permutations like words in a dictionary: 123, 132, 213, 231, 312, 321. The next permutation is made with the smallest possible change at the end of the array:

Read the full explanation ↓
Input:
n=5PDF export

The next permutation of 1 3 5 4 2 in dictionary order is 1 4 2 3 5.

  1. def next_permutation(a):
  2. i = len(a) - 2
  3. while i >= 0:
  4. if a[i] < a[i + 1]:
  5. break
  6. i = i - 1
  7. if i < 0:
  8. a.reverse()
  9. return a
  10. j = len(a) - 1
  11. while True:
  12. if a[j] > a[i]:
  13. break
  14. j = j - 1
  15. a[i], a[j] = a[j], a[i]
  16. a[i + 1:] = reversed(a[i + 1:])
  17. return a

Invariant: The part a[i+1..] is decreasing, so every permutation starting with a[0..i] has been used up.

Start

1031524324

Local variables

Orange = changed in this step

a list

13542

Call stack

  1. next_permutation()line 1
Step 1 of 22
Black = swap, wrap · Orange = key stepcompare: 0/5 · swap: 0/1 · reverse_tail: 0/1

    How the work grows with input size

    Average of 12 random graphs per n (fixed seeds). Hollow marker = the input on screen.

    • comparisons
    • current input (n=5)
    02464681012n = number of itemscomparisons
    Show as a table
    ncomparisons
    42.5
    63.5
    83.9
    103.1
    122.8
    Explanation

    The idea

    Order the permutations like words in a dictionary: 123, 132, 213, 231, 312, 321. The next permutation is made with the smallest possible change at the end of the array:

    1. Walk back from the end to the first i with a[i] < a[i + 1] (the first "dip"). Everything after i is decreasing, so no other permutation is left for this prefix.
    2. From the end, find the smallest item larger than a[i] (a[j]) and swap them.
    3. Reverse the tail a[i+1..] so it becomes increasing (its smallest order).

    If there is no dip, the array is the last permutation; reversing it all gives the first.

    Cost

    O(n) per permutation. Repeated from a sorted array, it produces all n! permutations without repeats, even with repeated items.

    What to watch in the trace

    • The i arrow is where the dip is, and j is the item it is swapped with.