◀ THE GRIND — BACKTRACKING

N Queens II

The drill: Same board, no boards to draw — just count how many ways n queens can occupy an n×n grid with none attacking another along any row, column, or diagonal.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

A board size n arrives, and the task is the counting twin of the classic queens puzzle: instead of drawing every valid board, just report how many ways n queens can be placed on an n×n board with none attacking another.

The same rules apply as always — no two queens sharing a row, a column, or either diagonal — but nothing about the boards themselves needs to be produced or stored, only their total count.

Some sizes of n admit no valid arrangement at all, in which case the honest count is zero.

EX 01
n = 1
1
MINIMUM SIZE, ONE QUEEN ALONE
EX 02
n = 2
0
NO PLACEMENT ESCAPES ATTACK ON A 2X2 BOARD
EX 03
n = 3
0
STILL NO VALID PLACEMENT ON A 3X3 BOARD
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

The placement logic here is identical to arranging n non-attacking queens — the only thing that changes is what you keep at the end. What's cheaper to build when the boards themselves are never needed?

HINT 2 THE STRUCTURE

Columns and diagonals are each just a range of n positions — instead of three sets of used values, represent 'taken' as bits in three integers, and 'free right now' is the complement of their union.

HINT 3 ONE STEP FROM THE ANSWER

Backtrack row by row over an integer bitmask: peel off one available bit at a time with avail & -avail, recurse with that column and both diagonals marked (shifting the diagonal masks by one row as you descend), and bump the counter only when every row is filled.

COACH'S BOARD — THE PATTERN, STEP BY STEP
THE BIT COUNTPATTERN · BITMASK BACKTRACKINGn = 4 · count only, no boards stored
STEP 1

n = 4. No board is built — cols, diag1, diag2 pack into three integers, and avail = full & ~(cols|diag1|diag2).

STEP 1 / 10 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/n-queens-ii.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def totalNQueens(self, n: int) -> int:
        full = (1 << n) - 1
        count = 0

        def backtrack(cols: int, diag1: int, diag2: int) -> None:
            nonlocal count
            if cols == full:
                count += 1
                return
            avail = full & ~(cols | diag1 | diag2)
            while avail:
                bit = avail & (-avail)
                avail -= bit
                backtrack(cols | bit, (diag1 | bit) << 1 & full, (diag2 | bit) >> 1)

        backtrack(0, 0, 0)
        return count
TIME O(N!)SPACE O(N)PYTHON · RACE PACE · 18 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED