Luke a Pro

Luke Sun

Developer & Marketer

šŸ‡ŗšŸ‡¦

Backtracking

| , 4 minutes reading.

Backtracking: The Courage to Turn Back

The Story: The Maze

Imagine you are in a massive stone maze. You want to find the exit.

  • You reach a fork: Left or Right? You pick Left.
  • You walk for 10 minutes and hit a dead end.
  • Do you sit down and cry? No. You walk back to the last fork and try the Right path.

This is Backtracking. It is a systematic way of trying every possible candidate for a solution. If a candidate cannot possibly lead to a valid solution, the algorithm ā€œBacktracksā€ (undoes the last step) and tries the next candidate.

It is essentially DFS (Depth-First Search) on a tree of decisions.

Why do we need it?

  • Puzzles: Solving Sudoku, Crosswords, or the Rubik’s Cube.
  • Optimization: The N-Queens problem—placing 8 queens on a chessboard so none can attack each other.
  • Combinatorics: Generating all possible passwords of length 8.
  • Resource Management: Assigning tasks to workers with complex constraints.

How the Algorithm ā€œThinksā€

The algorithm follows a simple recursive template:

  1. State: What does the solution look like right now?
  2. Choices: What are the possible next steps?
  3. Constraint Check: Is this next step legal?
  4. Goal: Have we finished?
  5. The Undo: If we hit a wall, remove the last choice and try the next one.

Pruning: A smart adventurer doesn’t walk 10 minutes into a path if they can see a ā€œDead Endā€ sign at the entrance. In backtracking, Pruning is the act of cutting off entire branches of the decision tree early because they violate a rule.

Engineering Context: The State Space Explosion

Backtracking can be very slow because the number of possibilities grows exponentially (O(2N)O(2^N) or O(N!)O(N!)).

  • Optimization: Engineers use ā€œHeuristicsā€ to try the most likely paths first.
  • Fail Early: The sooner you can detect a dead end, the faster the algorithm runs.

Implementation (Python)

# The N-Queens Problem: Place N queens on an NxN board
def solve_n_queens(n):
    result = []
    board = [['.' for _ in range(n)] for _ in range(n)]
    
    def is_safe(row, col):
        # Check column
        for i in range(row):
            if board[i][col] == 'Q': return False
        # Check upper-left diagonal
        for i, j in zip(range(row-1, -1, -1), range(col-1, -1, -1)):
            if board[i][j] == 'Q': return False
        # Check upper-right diagonal
        for i, j in zip(range(row-1, -1, -1), range(col+1, n)):
            if board[i][j] == 'Q': return False
        return True

    def backtrack(row):
        # Base Case: Goal reached
        if row == n:
            result.append(["".join(r) for r in board])
            return

        # Try all choices (columns)
        for col in range(n):
            if is_safe(row, col):
                # 1. Make Choice
                board[row][col] = 'Q'
                # 2. Explore
                backtrack(row + 1)
                # 3. Undo Choice (The Backtrack)
                board[row][col] = '.'

    backtrack(0)
    return result

# Usage
solutions = solve_n_queens(4)
print(f"Number of ways to place 4 queens: {len(solutions)}")

Summary

Backtracking teaches us that exploration requires humility. We must be willing to admit when we are wrong and have the discipline to return to the last point of certainty. It reminds us that in a world of infinite possibilities, the only way to find the truth is to try everything—and know when to stop.