N Queens Problem in DSA Typescript - Time & Space Complexity
We want to understand how the time needed to solve the N Queens problem grows as the board size increases.
Specifically, how does the number of steps change when we try to place queens on larger boards?
Analyze the time complexity of the following code snippet.
function solveNQueens(board: number[][], row: number, n: number): boolean {
if (row === n) return true;
for (let col = 0; col < n; col++) {
if (isSafe(board, row, col, n)) {
board[row][col] = 1;
if (solveNQueens(board, row + 1, n)) return true;
board[row][col] = 0;
}
}
return false;
}
This code tries to place queens row by row, checking if each position is safe, and uses backtracking to find a solution.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for-loop tries all columns in a row, and the recursive call tries to place queens in the next row.
- How many times: For each row, it tries up to n columns, and this repeats recursively for n rows, exploring many board states.
As the board size n grows, the number of ways to place queens grows very fast because each row tries many columns and backtracks often.
| Input Size (n) | Approx. Operations |
|---|---|
| 4 | Hundreds of checks |
| 8 | Thousands to tens of thousands of checks |
| 12 | Millions of checks |
Pattern observation: The operations grow faster than just multiplying by n; it grows roughly like n factorial because of the many possible queen placements.
Time Complexity: O(n!)
This means the time needed grows very fast, roughly like the number of ways to arrange queens on the board, making it hard for large n.
[X] Wrong: "The algorithm only checks n positions per row, so it should be O(n^2)."
[OK] Correct: Because it tries many combinations recursively, the total checks multiply across rows, leading to factorial growth, not just squared.
Understanding this problem's time complexity helps you explain why backtracking can be expensive and when to expect slow solutions, a useful skill in interviews.
"What if we added pruning to stop early when conflicts are detected? How would the time complexity change?"
Practice
N Queens Problem?Solution
Step 1: Understand the problem statement
The N Queens Problem asks to place N queens on an NxN chessboard so that no two queens threaten each other.Step 2: Identify the correct goal
This means no two queens share the same row, column, or diagonal.Final Answer:
Place N queens on an NxN chessboard so that no two queens attack each other -> Option AQuick Check:
Goal = Place queens safely [OK]
- Thinking queens can share rows or columns
- Confusing the problem with counting queens
- Ignoring diagonal attacks
Solution
Step 1: Identify correct parameter types for recursion
The recursive function usually takes the current row (number) and the board state (2D array) to place queens step-by-step.Step 2: Match function signature with recursion needs
function solveNQueens(row: number, board: number[][]): boolean usesrow: numberandboard: number[][], suitable for recursion and board tracking.Final Answer:
function solveNQueens(row: number, board: number[][]): boolean -> Option DQuick Check:
Recursive function needs row and board parameters [OK]
- Using wrong parameter types like string for row
- Missing board state parameter
- Wrong return type for recursion
function isSafe(board: number[][], row: number, col: number): boolean {
for (let i = 0; i < col; i++) {
if (board[row][i] === 1) return false;
}
for (let i = row, j = col; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] === 1) return false;
}
for (let i = row, j = col; i < 4 && j >= 0; i++, j--) {
if (board[i][j] === 1) return false;
}
return true;
}
const board = [
[0, 0, 0, 0],
[1, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
];
console.log(isSafe(board, 1, 1));Solution
Step 1: Check row left side for queen
Forrow=1, col=1, check columns 0 to 0 in row 1. board[1][0] = 1, so return false.Step 2: No need to check diagonals as left row check failed
Since a queen is found on the left in the same row, position is unsafe.Final Answer:
false -> Option AQuick Check:
Left row check finds queen = false [OK]
- Ignoring left row check
- Confusing true/false return values
- Assuming diagonals checked first
function placeQueens(board: number[][], col: number): boolean {
if (col >= board.length) return true;
for (let i = 0; i < board.length; i++) {
if (isSafe(board, i, col)) {
board[i][col] = 1;
if (placeQueens(board, col + 1)) return true;
board[i][col] = 0;
}
}
return false;
}
// isSafe function is correctWhat is the bug?
Solution
Step 1: Analyze base case correctness
The base casecol >= board.lengthcorrectly stops recursion when all columns are processed.Step 2: Check backtracking and row iteration
The loop tries all rows in the current column, places queen if safe, recurses, and backtracks if needed.Final Answer:
No bug; the code works correctly -> Option BQuick Check:
Backtracking and base case are correct [OK]
- Changing base case incorrectly
- Missing backtracking step
- Assuming incomplete row checks
Solution
Step 1: Recall known solution counts for N=5
For a 5x5 board, the total number of distinct solutions is known to be 10 when counting all unique placements.Step 2: Confirm counting method
Since rotations and reflections are counted separately, the count remains 10.Final Answer:
10 -> Option CQuick Check:
N=5 solutions = 10 [OK]
- Confusing unique solutions with symmetrical counts
- Mixing counts for N=4 and N=5
- Assuming fewer solutions than actual
Ready to prove it?
Pass the test and this pattern moves unknown
