Generating Permutations
Backtracking that generates all n! orderings by choosing an unused element for each position and undoing it on return.
Worth knowing first
#How does it work?
A permutation is an ordering of the elements. n distinct elements have n! (n factorial) permutations: n choices for the first position, n − 1 for the second, and so on.
With backtracking, each position gets an element not used yet; it is marked as used and we move to the next position. When every position is filled, a permutation is recorded. On the way back the choice is undone and the next element is tried for the same position.
The search tree has n nodes on its first level and n · (n − 1) on the second; it has n! leaves. Trying elements in increasing order produces the permutations in lexicographic order.
#Try it yourself
Found (0)
We generate every ordering of the numbers 1 … n. Each level picks a number not used yet; when a branch is done the choice is undone.
#Step by step
- 01Start with an empty chosen list and no element used.
- 02For each unused element: choose it, mark it used and move to the next position.
- 03If every position is filled, record the permutation.
- 04On the way back, undo the choice and the mark (backtracking).
#Example code
The same algorithm in 8 languages. Every program is compiled, run and checked to print the same output.
def permutations(items: list) -> list:
out, chosen, used = [], [], [False] * len(items)
def visit() -> None:
if len(chosen) == len(items):
out.append(list(chosen))
return
for i, x in enumerate(items):
if used[i]:
continue
used[i] = True
chosen.append(x)
visit()
chosen.pop() # undo the choice (backtrack)
used[i] = False
visit()
return out
for p in permutations([1, 2, 3]):
print(" ".join(map(str, p)))#Complexity
| Operation | Time |
|---|---|
| Number of permutations | n! |
| Generating them all | O(n · n!) |
| Memory (recursion + marks) | O(n) |
| In-place swapping | O(n · n!), no extra array |
n! grows very fast: 10 elements mean 3.6 million permutations, 13 elements over 6 billion. Trying every permutation only works for small n; larger problems need pruning, DP or heuristics.
#When to use it?
Brute-force searches over small orderings (e.g. a travelling salesman with a few cities), generating anagrams, trying every order of test steps and puzzle solvers all generate permutations.
#Practice
Log in to answer questions and save your progress.
Easy
How many permutations do n distinct elements have?
- 1n!
- 22ⁿ
- 3n²
- 4n
What is the "used" array for?
- 1Prevents choosing the same element twice in one permutation
- 2Sorts the permutations
- 3Counts the permutations found
- 4Saves memory
Trying elements in increasing order for 1, 2, 3, in what order do permutations come out?
- 1Lexicographic order
- 2Random order
- 3Reverse order
- 4By length
Medium
How many nodes (excluding the root) does the search tree have for n = 3?
- 115
- 26
- 39
- 427
Hard
What is the time complexity of generating all permutations?
- 1O(n · n!)
- 2O(n!)
- 3O(2ⁿ)
- 4O(n²)