N Queens Problem Algorithm - All Solving Methods

A comprehensive comparison of every algorithm for solving the N queens problem: brute force, backtracking, branch and bound, constraint propagation, local search heuristics, and genetic algorithms. Includes complexity analysis and pseudocode for each approach.

Overview & Comparison

The N queens problem asks: how many ways can N non-attacking queens be placed on an N×N chessboard? It is a fundamental benchmark problem in combinatorial optimization and artificial intelligence. Different algorithms tackle it with very different trade-offs between completeness, optimality, and speed.

Key dimensions to compare algorithms:

  • Complete: Does it guarantee finding all solutions?
  • Optimal: Does it find a solution (or best solution) in minimum time?
  • Scalability: How does runtime grow with n?
  • Implementation complexity: How hard is it to implement correctly?

For most use cases — finding all solutions, education, or interview prep — backtracking is the right choice. For finding a single solution quickly in large n, min-conflicts heuristic is often fastest. For exploring the problem from an AI perspective, see the 8 Queens in AI guide.

Brute Force O(n^n)

The naivest approach: enumerate every possible placement of n queens on n² cells, checking each configuration for validity. This gives O(n^n) time complexity — for n=8 that is 8^8 = 16,777,216 configurations to check, most of them wildly invalid.

A slightly smarter brute force restricts to permutations of column assignments (one queen per row, one per column), yielding n! possibilities. For n=8 this is 8! = 40,320 — still much worse than backtracking in practice because it does not prune early.

Pseudocode:

for each permutation P of [0..n-1]:
    if noTwoDiagonalConflicts(P):
        record P as a solution

Verdict: Only suitable for educational illustration of why optimization matters. Never use for n > 8.

Backtracking O(n!)

Backtracking is the standard algorithm for the N queens problem. It builds solutions incrementally, abandoning partial solutions ("pruning") as soon as a constraint violation is detected. This reduces the effective search space from O(n^n) to approximately O(n!) and in practice to far fewer nodes.

Key insight: By placing exactly one queen per row, we eliminate row conflicts by design. The isSafe check then only needs to verify column and diagonal conflicts with already-placed queens.

Pseudocode:

function backtrack(board, row):
    if row == n: record solution; return
    for col in 0..n-1:
        if isSafe(board, row, col):
            board[row] = col
            backtrack(board, row+1)
            board[row] = -1  // undo

For complete language-specific implementations, see: Python, Java, C++, JavaScript.

Verdict: Best general-purpose algorithm for finding all solutions. Fast for n ≤ 15, feasible for n ≤ 20 with bitwise optimization.

Branch and Bound

Branch and bound extends backtracking by also tracking a lower bound on the number of conflicts in unexplored subtrees. When a subtree's lower bound exceeds the best-known solution quality, that branch is pruned.

For the N queens problem (where we want exact solutions, not approximate), the distinction from plain backtracking is subtle. The main enhancement is forward checking: after placing a queen, immediately compute which cells in remaining rows become unavailable. If any row has zero available columns, backtrack immediately rather than waiting to reach that row.

Forward checking pseudocode:

function solveFC(board, row, available[]):
    if row == n: record solution; return
    for col in available[row]:
        place queen at (row, col)
        newAvail = propagate constraints to rows row+1..n-1
        if all rows have at least 1 available cell:
            solveFC(board, row+1, newAvail)
        remove queen from (row, col)

Verdict: Forward checking typically reduces recursive calls by 2–5× compared to basic backtracking, especially for large n. More complex to implement but worth it for n ≥ 12.

Constraint Propagation

Constraint propagation, used in full Constraint Satisfaction Problem (CSP) solvers, applies arc consistency algorithms (AC-3) to aggressively reduce variable domains before and during search. The N queens problem maps cleanly to CSP:

  • Variables: Q₁, Q₂, ..., Qₙ (one per row)
  • Domains: Each variable has domain {0, 1, ..., n-1} (columns)
  • Constraints: All-different constraints for columns and both diagonal expressions

AC-3 propagates constraints between pairs of variables. When a queen is placed in column c, row r, the algorithm removes c from the domains of all later rows, removes r-c from the domains (via the main diagonal constraint), and removes r+c via the anti-diagonal constraint. This can reduce domains to size 1 or 0, triggering immediate assignment or backtracking.

Libraries like Python's python-constraint or Prolog's built-in CLP(FD) implement this automatically, reducing the N queens problem to a few lines of declarative code.

Verdict: Powerful for large CSPs. For N queens specifically, the overhead of AC-3 bookkeeping can make it slower than optimized backtracking for small n, but faster for n ≥ 20.

Genetic Algorithm

Genetic algorithms (GAs) model evolution: maintain a population of candidate solutions, select the fittest, combine them via crossover, and introduce mutations. For N queens:

  • Chromosome: A permutation of [0..n-1] representing column positions
  • Fitness: Number of non-attacking queen pairs (max = n*(n-1)/2)
  • Crossover: PMX (Partially Mapped Crossover) to preserve permutation validity
  • Mutation: Swap two column values

GAs are not competitive with backtracking for exact enumeration, but they illustrate evolutionary computation principles clearly. For a complete Python implementation, see the Genetic Algorithm guide.

Verdict: Educational value high; practical performance for exact enumeration low. Better suited for approximate or large-n single-solution scenarios.

Comparison Table

Algorithm Time Complexity Finds All? Best For Difficulty
Brute ForceO(n^n)YesEducation onlyEasy
BacktrackingO(n!)YesGeneral use, n ≤ 20Easy
Backtracking + BitwiseO(n!)*YesPerformance, n ≤ 25Medium
Branch & Bound / FCBetter than O(n!)Yesn ≥ 12, exactMedium
Constraint PropagationVariesYesLarge n, CSP frameworksHigh
Min-Conflicts~O(n) avgNoSingle solution, any nEasy
Simulated AnnealingDepends on scheduleNoSingle solution, robustMedium
Genetic AlgorithmDepends on paramsNoEducational, EA studyHigh

* With bitwise optimization, the constant factor is dramatically smaller even though asymptotic class is the same.

Preguntas Frecuentes

What is the best algorithm for the N queens problem?

It depends on the goal. For finding all solutions (complete enumeration), backtracking with bitwise optimization is best. For finding a single solution quickly at any scale, the min-conflicts heuristic finds a solution in O(n) average steps. For AI coursework, constraint propagation (CSP with AC-3) is often required.

What is the time complexity of backtracking for N queens?

O(n!) in the worst case. For n=8 this is 40,320, but constraint pruning reduces actual calls to roughly 15,720. With bitwise optimizations the constant factor shrinks by 10–50×. Brute force without pruning is O(n^n) — 1000× worse for n=8.

What is the difference between backtracking and branch and bound for N queens?

Standard backtracking checks conflicts only when a queen is placed. Branch and bound (with forward checking) additionally propagates constraints forward — after placing a queen, it immediately removes eliminated columns from all remaining rows. This allows earlier detection of dead ends, typically reducing recursive calls by 2–5× for n ≥ 10.

Can genetic algorithms solve the N queens problem exactly?

Not reliably. Genetic algorithms are stochastic and do not guarantee finding all solutions or even finding one within a fixed time. They can efficiently find one high-quality solution for large n, but backtracking is always preferred when exact enumeration is needed. See the Genetic Algorithm guide for implementation details.