N-Queens – Solution & Complexity

Solution Walkthrough

1. Recognize the Pattern

This is classic backtracking: place one queen per row, reject any column or diagonal conflict immediately, and let the recursion tree enumerate solutions in deterministic row-major DFS order.

2. Build the Algorithm

Track three conflict sets or boolean arrays: used columns, used main diagonals (row - col), and used anti-diagonals (row + col). For each row, try columns from 0 to n - 1; every valid placement recurses to the next row, and every complete placement becomes one output board.

3. Check Edge Cases

Handle the trivial n = 1 board, remember that n = 2 and n = 3 have no solutions, and be careful to copy the constructed board when a solution is found so later backtracking does not mutate saved answers.

4. Solution and Complexity

Time: O(n!) in the classic backtracking worst case. Space: O(n^2) counting the output boards plus O(n) recursion state and the current placement arrays.

def solve_n_queens(n: int) -> list[list[str]]:
    cols = [False] * n
    diag = [False] * (2 * n - 1)
    anti = [False] * (2 * n - 1)
    queens = [-1] * n
    result = []

    def build_board() -> list[str]:
        board = []
        for row in range(n):
            chars = ['.'] * n
            chars[queens[row]] = 'Q'
            board.append(''.join(chars))
        return board

    def dfs(row: int) -> None:
        if row == n:
            result.append(build_board())
            return

        for col in range(n):
            d = row - col + n - 1
            a = row + col
            if cols[col] or diag[d] or anti[a]:
                continue

            cols[col] = diag[d] = anti[a] = True
            queens[row] = col
            dfs(row + 1)
            queens[row] = -1
            cols[col] = diag[d] = anti[a] = False

    dfs(0)
    return result

FAQ