◀ THE GRIND — BACKTRACKING

Permutations

MEDIUM✓ CHIP-TIMEDLC #46 — FULL STATEMENT ↗

The drill: Every possible ordering of a list of distinct numbers, using every number exactly once — return them all.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

A list of distinct numbers arrives, and the task is to produce every possible ordering of it, using each number exactly once per ordering.

Order is the entire point: [1, 2] and [2, 1] are two different results here, unlike a subset or combination problem where only membership matters.

Every returned ordering must use all of the input numbers — none left out, none repeated within a single ordering — and every distinct ordering should appear exactly once.

EX 01
nums = [1]
[[1]]
MINIMUM SIZE
EX 02
nums = [1, 2]
[[1, 2], [2, 1]]
EX 03
nums = [1, 2, 3]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
CLASSIC N = 3
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

Order is the whole point here — [1, 2] and [2, 1] both count, so 'used before' isn't enough; you need 'used before, in this exact spot'.

HINT 2 THE STRUCTURE

At each position in the output, any number not yet placed is a legal next choice — build the ordering one slot at a time and undo the choice before trying the next.

HINT 3 ONE STEP FROM THE ANSWER

Swap the chosen value into the current position and recurse on the rest of the array, then swap back on the way out. The used/unused split becomes a plain array boundary — no scanning required.

COACH'S BOARD — THE PATTERN, STEP BY STEP
THE SWAP-INTO-PLACE RUNPATTERN · SWAP INTO PLACEnums = [1, 2, 3]
STEP 1

Three numbers, six orderings. Swap the chosen value into the current position, recurse on the rest, then swap back — no membership scan needed.

STEP 1 / 12 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/permutations.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []
        n = len(nums)

        def backtrack(i):
            if i == n:
                res.append(list(nums))
                return
            for j in range(i, n):
                nums[i], nums[j] = nums[j], nums[i]
                backtrack(i + 1)
                nums[i], nums[j] = nums[j], nums[i]  # swap back

        backtrack(0)
        return res
TIME O(N·N!)SPACE O(N)PYTHON · RACE PACE · 16 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED