Time complexity of N Queen using backtracking?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
The backtracking solution to the N-Queens problem is exponential, and the standard worst-case description is O(N!). That bound is not a claim that the algorithm literally explores every permutation in every run, but it is the right high-level way to express how the search space grows when you place queens row by row while forbidding reused columns.
Why the Search Space Looks Factorial
A typical backtracking solver places one queen per row. For each row, it tries columns that are not already occupied and also checks diagonals.
If you ignore diagonal pruning for a moment, the branching pattern looks like this:
- first row: up to
Nchoices - second row: up to
N - 1remaining columns - third row: up to
N - 2 - and so on
Multiplying those choices gives N!.
Diagonal constraints prune many branches earlier, which is why the solver is usually faster than a naive permutation scan in practice, but the algorithm is still exponential in growth and the common worst-case description remains factorial.
A Standard Backtracking Implementation
A compact Python implementation makes the structure clear.
The recursive structure is what drives the complexity: each valid partial placement spawns more candidate placements until the branch dies or becomes a full solution.
Why It Is Not N^N
You will sometimes see people say the complexity is O(N^N) because each row could try N columns. That is too loose for the standard row-by-row formulation because once a column is occupied, it is not tried again in deeper rows.
So O(N!) is the tighter common bound for the classic backtracking approach with one queen per row and one queen per column.
The diagonal checks do not change the factorial nature of the upper bound. They only reduce the practical search space.
Space Complexity
The auxiliary space cost is much smaller than the time cost.
A standard recursive solver stores:
- recursion depth up to
N - occupied columns
- occupied diagonals
- the current partial board
That leads to O(N) additional space, excluding the space used to store all solutions if you keep them.
If you store every valid solution, total output space can become much larger, but that is output cost rather than working memory for the search itself.
Practical Performance
Although the asymptotic bound is harsh, good constant-factor implementation choices matter.
Common speedups include:
- using boolean arrays or bitmasks instead of Python sets
- exploiting symmetry for the first row
- stopping after the first solution instead of enumerating all solutions
These improvements help real runtime significantly, but they do not change the underlying exponential character of the problem.
Common Pitfalls
Calling the algorithm polynomial because each step checks only a few constraints is a conceptual mistake. The recursion tree is the real cost driver.
Saying the complexity is exactly N! is also too strong. O(N!) is an upper-bound style summary, not an exact runtime formula for every implementation and input size.
Ignoring the difference between finding one solution and enumerating all solutions can also confuse the discussion. Enumerating all solutions is naturally more expensive.
Finally, do not mix output size with working memory. Time is exponential, while the typical backtracking working space is only linear in N.
Summary
- the classic row-by-row backtracking solver for N-Queens is commonly described as
O(N!)in worst-case time - that bound comes from choosing distinct columns across rows, with diagonal pruning reducing many branches in practice
- the algorithm is exponential even though individual safety checks are cheap
- working memory is usually
O(N)excluding stored solutions - optimizations improve practical speed, but they do not change the fundamental exponential search behavior
Related reading
- Time complexity of power
- Time complexity of Sieve of Eratosthenes algorithm
- Time complexity of System.arraycopy...?
- Time complexity of the Ford-Fulkerson method in a flow network with unit capacity edges
- Time complexity of Python 3.8's integer square root math.isqrt function
- Time Complexity of the Kruskal Algorithm?
- Time Complexity Of This Code Snippet
- Time Complexity of two for loops

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.