π Backtracking
One-line summary: Explore all possible solutions by incrementally building candidates and abandoning ("backtracking") as soon as a constraint is violated.
Diagramβ
Conceptβ
- Choose β pick a candidate.
- Explore β recurse with that choice.
- Unchoose β undo the choice, try next.
Prune early: if current state already violates a constraint, skip the subtree.
Time: O(b^d) where b = branching factor, d = depth. Space: O(d) for the call stack.
Common Patternsβ
Subsetsβ
function subsets(nums) {
const result = [];
function bt(start, curr) {
result.push([...curr]);
for (let i = start; i < nums.length; i++) {
curr.push(nums[i]);
bt(i + 1, curr);
curr.pop();
}
}
bt(0, []);
return result;
}
Permutationsβ
function permute(nums) {
const result = [],
used = new Array(nums.length).fill(false);
function bt(curr) {
if (curr.length === nums.length) {
result.push([...curr]);
return;
}
for (let i = 0; i < nums.length; i++) {
if (!used[i]) {
used[i] = true;
curr.push(nums[i]);
bt(curr);
curr.pop();
used[i] = false;
}
}
}
bt([]);
return result;
}
Constraint Satisfaction (N-Queens skeleton)β
function solve(row, board, result) {
if (row === board.length) {
result.push(board.map((r) => r.join('')));
return;
}
for (let col = 0; col < board.length; col++) {
if (isValid(board, row, col)) {
board[row][col] = 'Q';
solve(row + 1, board, result);
board[row][col] = '.'; // unchoose
}
}
}
Pitfallsβ
- Not spreading
[...curr]before pushing to result β captures reference - Missing pruning β O(b^d) blows up without early constraint checks
- Duplicate handling: sort input and skip duplicate values at same depth level
Practice Problemsβ
Related Topicsβ
- Recursion β backtracking is recursion with undo
- Dynamic Programming β DP memoises; backtracking explores
β Back to Home Β· Β© sparshjaswal