N-Queens
The n-queens puzzle is the problem of placing n queens on an n x n chessboard so that no two queens attack each other — meaning no two share a row, a column, or a diagonal . Given an integer n, return all distinct solutions, each represented as a board where "Q" marks a queen and "." marks an empty space. Use backtracking that places one queen per row: try every column in the current row, and prune any column already under attack from a queen placed in an earlier row — undoing the placement after each recursive call to free that column and its diagonals back up.
Constraints
- 1 ≤ n ≤ 9
Example
n = 4[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]Explanation Exactly two distinct arrangements place 4 non-attacking queens on a 4x4 board.
In plain terms
- Diagonal
- A line of cells running at a 45° angle — two cells share a diagonal whenever the difference, or the sum, of their row and column indices is equal.
Place one queen per row, prune any column already under attack
Row 0: place a queen in column 1 (no earlier queens to conflict with).
What happens in this step
row 0, col 1 — first queen, board empty
cols = {} diag1 (row-col) = {} diag2 (row+col) = {}
No sets have any entries yet, so every column is open. Column 1 is chosen and placed: cols={1}, diag1={-1}, diag2={1}. path=[1], recurse into row 1.Steps to visualize
- Move to the next row and try each column in turn.
- Skip a column immediately if it — or either of its diagonals — is already occupied by an earlier queen: that branch is pruned before it even starts.
- Place the queen, recurse into the next row, then undo the placement to free the column and diagonals back up.
- Once every row has a queen, record the board as one solution.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
Row 0: place a queen in column 1 (no earlier queens to conflict with).
What happens in this step
row 0, col 1 — first queen, board empty
cols = {} diag1 (row-col) = {} diag2 (row+col) = {}
No sets have any entries yet, so every column is open. Column 1 is chosen and placed: cols={1}, diag1={-1}, diag2={1}. path=[1], recurse into row 1.Solution
function solveNQueens(n) {
const result = [];
const cols = new Set();
const diag1 = new Set(); // row - col
const diag2 = new Set(); // row + col
const positions = [];
function backtrack(row) {
if (row === n) {
const board = positions.map((col) => '.'.repeat(col) + 'Q' + '.'.repeat(n - col - 1));
result.push(board);
return;
}
for (let col = 0; col < n; col++) {
if (cols.has(col) || diag1.has(row - col) || diag2.has(row + col)) {
continue; // prune — this column is already under attack
}
cols.add(col);
diag1.add(row - col);
diag2.add(row + col);
positions.push(col);
backtrack(row + 1);
cols.delete(col);
diag1.delete(row - col);
diag2.delete(row + col);
positions.pop();
}
}
backtrack(0);
return result;
}- Time
- O(n!)
- Space
- O(n)
Test cases
| Input | Expected | Covers |
|---|---|---|
n = 4 | [[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] | example from the docstring, the two 4x4 solutions |
n = 1 | [["Q"]] | smallest valid input, a single queen with no conflicts possible |
n = 2 | [] | a 2x2 board has no arrangement of two non-attacking queens |
n = 3 | [] | a 3x3 board also has no valid arrangement |