Good morning! Here's our prompt for today.
N-Queen Problem: The Chessboard Conundrum
Imagine stepping into an interview room, and the interviewer asks you to solve the N-Queen problem. It's a modern take on the classic 8-Queen Puzzle, where you place queens on a chessboard in such a way that none can attack another. Here's a complete guide to understanding the problem and constraints.
The Basic Rules of Chessboard and Queens
First, let's get our chess terminology straight. A queen in chess can move horizontally, vertically, and diagonally. Your task is to place n
queens on an n x n
chessboard in such a way that none of the queens are in a position to attack each other.
Key Assumptions
- Square Board: The chessboard will always be square-shaped.
- Solution Exists: For
n > 3
, at least one non-attacking arrangement of queens exists.
Constraints to Keep in Mind
Board Size Limitations
- Maximum value of
n
: The board can have up to 100 rows and columns. - Minimum value of
n
: The board must have at least 4 rows and columns.
Performance Expectations
- Time Complexity: Your solution should aim to have a time complexity of
O(n^2)
. - Space Complexity: Keep the space complexity at
O(n)
.
Example: Solving a 4x4 Board
For a 4x4 chessboard, you could place the queens like so (Q represents a queen, and . represents an empty space):
1. Q . .
2. . . Q
3Q . . .
4. . Q .
Here, no two queens threaten each other. And voila, you've successfully solved the 4-queen problem.
Grasp these guidelines well, and you'll be several moves ahead in your coding interview.
Try to solve this here or in Interactive Mode.
How do I practice this challenge?
xxxxxxxxxx
var assert = require('assert');
​
function solveNQueens(n) {
// Fill in
}
​
// test cases
​
try {
res = solveNQueens(4);
shouldbe = [
[
['.', 'Q', '.', '.'],
['.', '.', '.', 'Q'],
['Q', '.', '.', '.'],
['.', '.', 'Q', '.'],
],
[
['.', '.', 'Q', '.'],
['Q', '.', '.', '.'],
['.', '.', '.', 'Q'],
['.', 'Q', '.', '.'],
],
];
​
assert.deepEqual(shouldbe, res);
​
console.log('PASSED: ' + 'With n=4, there should be 2 solution boards.');
} catch (err) {
Here's how we would solve this problem...
How do I use this guide?
The N-Queens problem could stump you in an interview if you're not prepared. Let's break down how to tackle it efficiently, so you can make a smart move.
The Pitfall of Naive Brute Force
Sky-High Complexity
In an 8x8 board, the total number of possible arrangements is 8^8 = 16,777,216
. That's like combing through a haystack the size of a mountain to find your needle.
No Polynomial Shortcut
Since the N-Queens problem is an NP-complete issue, no polynomial time solution is known. Brute force? Definitely a checkmate against you.
The Ace Up Your Sleeve: Backtracking
Non-Sequential Exploration
Unlike brute-force, you don't have to check every single sequential queen placement. You can place queens in a way that's much smarter.
How Backtracking is Done
- Start Fresh: You begin with an empty chessboard.
- First Column, First Queen: Plant a queen in the first available column of the first row.
- Row Exploration: Iterate through each row, trying to find a spot where the queen can sit without being in the line of attack from any other queen.
- Retreat and Reconsider: If you can't find such a spot in the current row, it's time to backtrack. Go back to the previous row and move that queen to another column.
- Rinse and Repeat: Continue this process until you either find a valid arrangement of queens or have to admit defeat.
Why Backtracking Wins
Eliminates Dead-Ends
The algorithm smartly avoids going down pathways that are bound to fail, saving you precious time and computational power.
Prunes the Search Space
Because of the built-in constraint checks, you dramatically reduce the number of possible board configurations you need to explore.
Efficient & Optimal
It's like solving a puzzle where you can peek at the box cover whenever you want. You get hints that guide you to the optimal solution much faster.

With backtracking, you're not just coding; you're strategically navigating through constraints and possibilities, turning your code into a masterstroke of problem-solving.
Board Validation Function
Before we implement the solver itself, we need to create a function that can be used to see if we can put a queen on a cell in the board
. The function will take the board
, a row
, and a col
to place into that cell of the board.
1function validateBoard(board, row, col) {
2}
The function will first check if there is a Queen in the same column in the board. We can check this easily by looping through the rows one at a time. Notice that we do not need to check for queens after the current row because we have not reached that point yet. Here is the python code for this validation:
1// Check if row is valid
2for(let row_it = 0; row_it < row; row_it++){
3 if(board[row_it][col] == 'Q'){
4 return false;
5 }
6}
We do not need to check for Queens in the same column because in the backtracking process, we will put only one Queen at each column.
Following this, we will check if a Queen appears in the first diagonal of the board. To do this, we will need to see how the row_it
and the col_it
variables in a loop increases or decreases. See the below image to understand it. The first one is for the first diagonal and the second one is for the second diagonal.


xxxxxxxxxx
// Check if block has duplicate
let rowBlock = row - row % 3;
let colBlock = col - col % 3;
for (let rowIt = 0; rowIt < 3; rowIt++) {
for (let colIt = 0; colIt < 3; colIt++) {
if (board[rowBlock + rowIt][colBlock + colIt] === val) {
return false;
}
}
}
​
// Check if second diagonal is valid
for (let rowIt = row - 1, colIt = col + 1; rowIt >= 0 && colIt < board.length; rowIt--, colIt++) {
if (board[rowIt][colIt] === 'Q') {
return false;
}
}
Finally if none of these return False
, we are sure that a Queen at that row
and col
position is a valid state. So we will return true.
xxxxxxxxxx
// Everything is valid, so return true
return true;
Base Conditions of Recursing Backtracking
We will start from the first element in the board. We will be putting Queens in places and then move forward. To do this, we will continuously place Queens if possible, and then increment row
.
While incrementing row
, we will reach at a point where row
will be greater than n
(out of the board). At that time, we have found a solution. So we will save a copy of the board and continue to backtrack for other solutions.
xxxxxxxxxx
if (row === board.length) {
// A solution! add a copy of it
res.push([board]);
return res;
}
Recursive Backtracking
For the backtracking, we will take each row
and put a Queen in a feasible place (with the help of validate_board
) in that row
. After placing the Queen, we will recursively continue from the next row in the board.
After finishing that recursive function, we will have all the solved boards, putting a Queen at that row
and col
. We'll need the next step of putting current Queen in the next feasible place. That is why we will pick up the Queen (put '.' there) and continue the loop.
Finally there will be all the solutions in res
. Also, we will again be at the top of the call stack in the recursive function. So we will return our desired res
to the caller function.
xxxxxxxxxx
for(let col = 0; col < board.length; col++) {
if(this.validate_board(board, row, col)) {
// Put a queen and move forward
board[row] = board[row].substr(0, col) + "Q" + board[row].substr(col+1);
this.recursiveSolveNQueens(res, board, row+1);
// Now backtrack
board[row] = board[row].substr(0, col) + "." + board[row].substr(col+1);
}
}
Start of the Backtracking Algorithm
We will start the backtracking process from row=0
and col=0
. col=0
part is already taken cared by the backtracking function itself. We just need to create a board so that our recursiveSolveNQueens
can start playing with the board.
To create a board, we will first create a string of size n
with the python string multiplication operator '.' * n
. Then we will again duplicate it n
times to get the board.
xxxxxxxxxx
const solveNQueens = (n) => {
// For n=5, board in Javascript is
// [".....", => '.'*n
// ".....", => '.'*n
// ".....", => '.'*n
// ".....", => '.'*n
// "....."] => '.'*n
// so, [...Array(n)].map(_ => '.'.repeat(n))
let board = [Array(n)].map(_ => '.'.repeat(n));
// Type will be replaced by actual type later
};
Finally we will start the recursion with the board and an empty res
result list. res
will be the answer of our problem, so we can directly return it.
This is the most well-known algorithm for solving N-Queen problem. The time complexity is O(n^2)
because we are selecting if we can put or not put a Queen at that place. The space is the board size times the result. Note that, even though it seems that the time complexity is huge, it is actually not. The maximum value of n
will be only 100
.
One Pager Cheat Sheet
- You should design an
N-Queen
problem solver that can placen
queens on an x n
square board in a way that no queen is in a mutual attacking position, with a minimum value ofn = 4
and a maximum value ofn = 100
, inO(n^2)
time andO(n)
space complexity. - We need to use a
backtracking algorithm
to solve theNP-Complete 8-Queen problem
due to its large search space ruling out a naive brute force solution. - A
Board Validation Function
is used to check if we can place aQueen
in a cell of the board by looping through the rows and checking if there is a Queen in the same column, and by checking if a Queen appears in the first and second diagonals by observing therow
andcol
variables in a loop. We will return
Trueif a Queen is validly placed at a given
row
andcol
position.- We will start from the first element in the board and attempt to place Queens, incrementing the
row
untilrow
is greater thann
, at which point a solution is found and the board is saved for further backtracking. - The algorithm will recursively evaluate
row
-by-row
for valid positions to place the Queen and add each solution to a list ofresults
beforebacktracking
to the next feasible place. - We will
create a board
bymultiplying a string of size n
andduplicating it n times
, then start thebacktracking process
atrow=0 and col=0
. - We will recursively select
Q
ueen positions and build up the solution list,res
, with a time complexity of O(n^2) and space complexity of board size times res.
This is our final solution.
To visualize the solution and step through the below code, click Visualize the Solution on the right-side menu or the VISUALIZE button in Interactive Mode.
xxxxxxxxxx
}
var assert = require('assert');
​
function solveNQueens(n) {
var board = new Array(n);
// Setup thhe board
for (i = 0; i < n; i++) {
board[i] = new Array(n);
for (j = 0; j < n; j++) {
board[i][j] = '.';
}
}
​
res = recursiveSolveNQueens([], board, 0);
console.log('board', res);
return res;
}
​
function copyBoard(board) {
let newBoard = new Array(board.length);
for (i = 0; i < board.length; i++) {
newBoard[i] = new Array(board[i].length);
for (j = 0; j < board[i].length; j++) {
newBoard[i][j] = board[i][j];
}
}
return newBoard;
}
​
function recursiveSolveNQueens(res, board, row, cols = []) {
if (row === board.length) {
// A solution! add a copy of it
res.push(copyBoard(board));
Alright, well done! Try another walk-through.
If you had any problems with this tutorial, check out the main forum thread here.