Count the ways to place n queens on an n×n board with none attacking, using backtracking with column and diagonal sets for O(1) conflict checks.
The problem
Return how many ways n queens can be placed on an n × n chessboard so that no two attack each other (same row, column or diagonal).
Examples
Example 1
Input
n_queens(4)
Expected output
2
Example 2
Input
n_queens(1)
Expected output
1
+ 4 hidden tests on Submit.
Edge cases to ask about
- n = 1
- n = 2 and 3 (no solution)
Hints
0/3How an interviewer scores this
0/9Your code runs in real CPython inside your browser — nothing is sent anywhere. The first run downloads the interpreter (about 6 MB, once). Your code is saved on this device as you type.
Complexity Lab
What does this cost as n grows?
Interviewers score the analysis as much as the code. Commit to an answer first — then check it, and read why.
Pick both to reveal the answer.
From brute force to optimal
The progression an interviewer wants to hear, one step at a time.
| Approach | Time | Space | Idea |
|---|---|---|---|
| Try every placement of n queens | O(n²ⁿ) | O(n) | |
| One queen per row + conflict sets | O(n!) | O(n) | row − col and row + col identify the two diagonals. |
| bestBitmasks | O(n!) | O(n) | Same search, much smaller constant. |
Walkthrough of the optimal approach (try it yourself first)
Place one queen per row. Track the used columns and the two diagonal families: cells on the same "" diagonal share row − col, on the same "/" diagonal share row + col. Each conflict check is then an O(1) set lookup.
The skeleton — choose, recurse, un-choose — is the template for every backtracking problem. Pruning early (skipping attacked columns) is what keeps it tractable.
Complexity: O(n!) time, O(n) space. Row r has at most n − r safe columns left, so the search tree is bounded by n!; the sets and recursion hold O(n).
Reveal the reference solution
def n_queens(n): cols, diag, anti = set(), set(), set() def place(row): if row == n: return 1 count = 0 for c in range(n): if c in cols or row - c in diag or row + c in anti: continue cols.add(c); diag.add(row - c); anti.add(row + c) count += place(row + 1) cols.remove(c); diag.remove(row - c); anti.remove(row + c) return count return place(0)
Follow-ups interviewers ask
- Return the boards themselves.
- Rewrite with bitmasks.
Frequently asked interview questions
Core interview concepts, complexities, and follow-ups scored by hiring teams.
What is the time complexity of N-Queens: Count All Solutions in Python?
The optimal solution runs in O(n!) time and O(n) auxiliary space. Row r has at most n − r safe columns left, so the search tree is bounded by n!; the sets and recursion hold O(n).
What is the brute-force approach, and how do you optimise it?
Try every placement of n queens: O(n²ⁿ) time, O(n) space. One queen per row + conflict sets: O(n!) time, O(n) space. row − col and row + col identify the two diagonals. Bitmasks: O(n!) time, O(n) space. Same search, much smaller constant.
What follow-up questions do interviewers ask about N-Queens: Count All Solutions?
Return the boards themselves. Rewrite with bitmasks.
