Given n distinct integers, list all n! orderings — grow one prefix at a time, trying every still-unused number in the next slot and undoing each choice on the way back.
Fix one slot at a time, try every unused number in it, then un-choose and try the next.
A permutation is built left to right: at every moment only the next empty slot is a decision, and its candidates are exactly the numbers not already placed. The recursion goes deep on the first candidate before the loop ever advances — that depth-first order is what enumerates every ordering without repetition.
Step through [1, 2, 3]. Each frame fixes one slot or undoes it; the six lime frames are the moments the path reaches full length and a copy is recorded.
class Solution:
def permute(self, nums):
res = []
used = [False] * len(nums)
def dfs(path):
if len(path) == len(nums): # full length: one complete order
res.append(path[:]) # copy: path keeps mutating
return
for i, x in enumerate(nums): # every candidate for this slot
if used[i]:
continue
used[i] = True
path.append(x)
dfs(path)
path.pop() # undo: free the slot for the next candidate
used[i] = False
dfs([])
return res
The displayed Python and the trace above use the same logic: full-length copy, skip-used loop, and paired undo. (An in-place swap variant exists; this used-array form makes the invariant visible.)
if len(path) == len(nums)The only place answers are recorded. Nothing shorter is ever emitted, and every full-length path is copied exactly once.if used[i]: continueEach level tries each value at most once and never reuses a prefix member — that is why branches are distinct with no dedup pass.path.pop(); used[i] = FalseBoth halves of the choice revert together. Forgetting either leaks state into every later sibling of the loop.Fixing 1 first yields [1,2,3] then [1,3,2] before 2 ever takes slot 0 — depth-first, not breadth. The trace's first two lime frames are exactly that pair.
The smallest non-trivial case: two candidates for slot 0, one forced pick each after. Edge [1] returns [[1]] — the loop runs once and the full-length test fires immediately.
I depth-first search over prefixes: at each level I try every unused number in the next slot, mark it used, recurse, then pop and unmark so siblings start clean. When the path reaches full length I copy it — that copy is one permutation, and the loop order yields all n factorial exactly once.