InterviewPrepKit

Home / Coding / Backtracking

N-Queens

hard Original β†—
Solving tips
  • Reframe the choice so a structural constraint is free: place exactly one queen per row, so the only decision per row is which column.
  • Track three sets for O(1) conflict checks: used columns, used r-c (the \ diagonals), and used r+c (the / diagonals).
  • The main difficulty is diagonals, not columns; forgetting r-c vs r+c or reusing one for both directions accepts illegal boards.
  • Time is O(n!) with O(n) extra space; undo all three sets plus the path on backtrack, and build each rendered row string independently to avoid aliasing.

Problem

Place n chess queens on an n x n board so that no two queens attack each other β€” no two share a row, a column, or a diagonal. Return all distinct valid placements. Each placement is rendered as a list of n strings of length n, where 'Q' marks a queen and '.' an empty square. Solutions may be returned in any order.

Examples

  • n = 4 β†’ two solutions:
. Q . .      . . Q .
. . . Q      Q . . .
Q . . .      . . . Q
. . Q .      . Q . .

Each is the other’s mirror image; no smaller-than-4 board other than n=1 admits any solution.

  • n = 1 β†’ [["Q"]] β€” a lone queen attacks nothing.
  • n = 2 β†’ [] β€” on a 2Γ—2 board every pair of squares shares a row, column, or diagonal.

Constraints

  • 1 <= n <= 9 β€” solution counts stay small (352 for n=9), but the raw search space is enormous, so pruning row-by-row is the expected shape.

Think about it first

Hint 1 Every valid placement has exactly one queen per row. So instead of choosing 9 squares among 81, place queens row by row: the only decision for row `r` is *which column* gets the queen.
Hint 2 Placing row by row already rules out row conflicts. To reject a column choice instantly, keep three "occupied" sets: columns, one per diagonal direction. What single number identifies the β†˜ diagonal through cell (r, c)? What identifies the ↙ diagonal?
Hint 3 Cells on the same β†˜ diagonal share `r - c`; cells on the same ↙ anti-diagonal share `r + c`. Backtrack over rows: for each free column `c` in row `r` (i.e. `c`, `r-c`, `r+c` all unused), place, recurse to row `r+1`, then remove. When `r == n`, render the column list into board strings.
Your workspace Not runnable by design β€” this is your interview scratchpad. Saved on this device.