Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Coding Interview Patterns  Module 16 – Backtracking

Permutations and next permutation

List every permutation with used flags or swaps, skip repeated orderings, find the next permutation in place and build the k-th one from factorials.

  • Intermediate
  • 35 minutes
  • Examples run with Python 3.14.8, Pyodide 314.0.7, Node.js 24.21.0, quickjs 0.32.0, Java 25, Clang 21.0.0 and Go 1.27.1
  • By MySmartCoPilot
Free intro, Pro: 8 of 35 minutes free
Free: Two problems about orderings · The brute force, and why it fails · What to notice. With a pass: the other 10 sections and 3 interview answers, about 27 minutes.

What you will learn

  • Generate every permutation of a list with used flags or with swaps
  • Avoid repeated orderings when values repeat
  • Compute the next permutation in place in O(n) time, and prove it is the very next one
  • Build the k-th permutation directly from factorials, and its rank from an ordering
  • Detect where 64-bit factorials stop in Java, C++ and Go

Before you start

What you’ll learn · Before you start

What you will learn

  • Generate every permutation of a list with used flags or with swaps
  • Avoid repeated orderings when values repeat
  • Compute the next permutation in place in O(n) time, and prove it is the very next one
  • Build the k-th permutation directly from factorials, and its rank from an ordering
  • Detect where 64-bit factorials stop in Java, C++ and Go

Before you start

On this page

A permutation is one ordering of a list’s items, and n different items have n! permutations: 24 for four items, 3,628,800 for ten. Listing all permutations places the items one position at a time, as a backtracking search. The next permutation of an ordering is the one right after it in sorted order. It can be found in place, in O(n) time, without listing any others. Four tools cover the family. Used flags mark which items are already placed. Swaps keep the unplaced items inside the list itself. A skip rule stops equal values from being tried twice at one position. Dividing by factorials builds the k-th permutation directly.

Two problems about orderings

Problem A: every seating. Write seatings(guests, pair), which lists every order of the guests in a row of seats in which the two guests of pair sit side by side. Limits: n ≤ 9. For guests A, B, C and D with the pair A and B, 12 of the 24 orders qualify, from ABCD to DCBA. A variant lists the distinct orderings of values that repeat. Their number is n! divided by the orderings of each group of equal values: toffee has 6! / (2! × 2!) = 180.

Problem B: the next code. A display shows a code of n digits. Its next code is the smallest code larger than it that uses exactly the same digits; after the largest comes the smallest. Rearrange the digits in place, with O(1) extra memory. Limits: 1 ≤ n ≤ 10⁵.

  • 534976 becomes 536479.
  • 4321 becomes 1234: it was the largest.
  • 1155 becomes 1515, with repeated digits.

The brute force, and why it fails

Try every ordering. For A, keep those where the pair sits together. For B, keep the smallest ordering above the code, which is its next permutation:

Both problems by trying every ordering, timed Python · brute/brute_force.py
"""Both problems by brute force: try every ordering, then keep what the problem asks for."""
import math
import time
from itertools import permutations


def next_code_brute(code):
    """The smallest ordering of the digits that is larger than code; after the largest comes the smallest."""
    current = tuple(code)
    larger = (p for p in permutations(code) if p > current)  # every ordering of the positions: n! of them
    best = min(larger, default=None)
    return "".join(best if best is not None else sorted(code))


def seatings_brute(guests, pair):
    """Every seating order in which the two guests of pair sit side by side."""
    a, b = pair
    return ["".join(p) for p in permutations(guests) if abs(p.index(a) - p.index(b)) == 1]


print(next_code_brute("534976"), next_code_brute("4321"), next_code_brute("1155"))
orders = seatings_brute("ABCD", ("A", "B"))
print(f"{len(orders)} of {math.factorial(4)} seating orders keep A and B together: {' '.join(orders)}")

print("digits  orderings tried  time")
for code in ["31415926", "314159265", "3141592653"]:
    start = time.perf_counter()
    next_code_brute(code)
    seconds = time.perf_counter() - start
    print(f"{len(code):>6} {math.factorial(len(code)):>16,}  {seconds:.2f} s")
print(f"12 digits: {math.factorial(12):,} orderings; 20 digits: {math.factorial(20):,}")

Output

536479 1234 1515
12 of 24 seating orders keep A and B together: ABCD ABDC BACD BADC CABD CBAD CDAB CDBA DABC DBAC DCAB DCBA
digits  orderings tried  time
     8           40,320  0.00 s
     9          362,880  0.17 s
    10        3,628,800  1.72 s
12 digits: 479,001,600 orderings; 20 digits: 2,432,902,008,176,640,000

This output changes from run to run: the times depend on the computer and on what else it is doing

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 brute_force.py

Each digit multiplies the work: 10 digits take seconds, 12 digits need 479,001,600 orderings and 20 digits need 2.4 × 10¹⁸. At 10⁵ digits the brute force cannot even start. For A it is acceptable, because the answer itself has tens of thousands of orderings at 9 guests, but it still builds every ordering before checking the pair.

What to notice

The code 534976: its last three digits 9, 7, 6 never increase, and the digit 4 before them is smaller than the 9 after it.the code 534976, read from the right5349769 ≥ 77 ≥ 64 < 9never increases: already the largestorder of the digits 9, 7 and 6the change must happen here

Reading 534976 from the right

Text description of the diagram

The diagram shows the six digits of the code 534976 in a row of boxes: 5, 3, 4, 9, 7 and 6. Read from the right, 7 is at least 6 and 9 is at least 7, so the last three digits, 9, 7 and 6, are shaded and marked with a bracket: from left to right they never increase. That is already the largest order of those three digits, so rearranging them alone cannot make the code larger.

The digit 4 before them has a bold outline. It is the first digit from the right that is smaller than the digit after it, 4 against 9, and a dashed line marks it as the place where the change to the next larger code must happen.

Read the code from the right. While the digits never increase, the suffix is already the largest order of its own digits, so rearranging it alone cannot give a larger code. The change must happen at the first digit, from the right, that is smaller than the digit after it. For A, a guest of the pair whose two neighbouring seats are taken by others can never sit by its partner, so that branch can stop at once.

Next permutation in four steps, with a dry run Pro: opens with a Pro, Premium or Ultimate pass

In this part:

  • Why the four steps give the very next ordering, with a proof
  • The code in five languages
    • Checked against the brute force on 3,092 codes
  • Listing every ordering: used flags or swaps
    • Pruning the seating search, measured
    • Repeated values: the skip rule for orderings
  • The k-th ordering, directly from factorials
    • Exercise: the k-th seating order
    • The k-th seating order without listing the others
  • Variants
  • Edge cases and common bugs
  • A practice set with answers
  • Check yourself
  • Interview questions
    • How many orderings do n items have when they are all different, and how many distinct ones when some repeat?
    • A booking system issues ticket codes as rearrangements of a fixed set of digits, each code the next larger one after the last. A teammate's function returns a larger rearrangement, but some codes are never issued. How do you compute the very next code in place, and how do you show that none is skipped?
    • A seating planner must show the k-th seating of 20 guests in sorted order, for any k up to 20!, without listing the seatings before it. How do you compute it, which integer types hold k in Java, C++ and Go, and what changes at 21 guests?
    • A word game must list every distinct arrangement of the letters of a 12-letter word with many repeated letters. Generating all orderings and removing repeats with a set takes minutes. Why, how do you list each distinct arrangement once, and how many are there for aabbccddeeff?
  • Key takeaways

8 runnable examples (C++, Go, Java, JavaScript, Python) · 1 exercise with sample tests · 3 interview answers · about 22 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.