The n-queens puzzle is the problem of placing n
queens on an n x n
chessboard such that no two queens attack each other.
Given an integer n
, return all distinct solutions to the n-queens puzzle. You may return the answer in any order.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q'
and '.'
both indicate a queen and an empty space, respectively.
Example 1:
Input: n = 4 Output: [[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above
Example 2:
Input: n = 1 Output: [["Q"]]
Constraints:
1 <= n <= 9
The N-Queens problem involves placing N chess queens on an N×N chessboard so that no two queens threaten each other. This means no two queens can share the same row, column, or diagonal.
The most efficient approach is using backtracking, a depth-first search (DFS) algorithm. We explore possible queen placements, and if a placement leads to a conflict, we backtrack to try a different placement.
State Representation: We use three arrays to track queen placements:
col
: Tracks column occupancy (1 if a queen is in that column, 0 otherwise).dg
: Tracks main diagonal occupancy (index represents the sum of row and column indices).udg
: Tracks anti-diagonal occupancy (index represents the difference between column and row indices, offset to avoid negative indices).DFS (Backtracking): The core of the solution is the recursive dfs(row)
function:
row == n
, we've placed all queens successfully. We add the current board configuration to the result.colIdx
in the current row
:
col[colIdx]
, dg[row + colIdx]
, or udg[n - 1 + colIdx - row]
is 0 (no conflict), we can place a queen.dfs(row + 1)
to place a queen in the next row.Initialization: Before starting the DFS, initialize the arrays col
, dg
, and udg
to 0. The chessboard is also represented as a 2D array (or list of lists in Python) initially filled with empty spaces (.
).
Time Complexity: O(N!) - In the worst case, we might explore all possible permutations of queen placements. The time complexity is dominated by the number of possible placements, which is factorial in nature. While each check within the DFS is O(1), the sheer number of potential paths makes the factorial complexity dominant.
Space Complexity: O(N) - The space used is mainly for the three arrays (col
, dg
, udg
), the recursive call stack (which can reach a depth of N), and the final result, all of which are linear in N.
def solveNQueens(n):
def is_safe(row, col):
for i in range(row):
if queens[i] == col or abs(queens[i] - col) == row - i:
return False
return True
def solve_util(row):
if row == n:
result.append([["."]*n for _ in range(n)])
for i in range(n):
result[-1][i][queens[i]] = "Q"
return True
for col in range(n):
if is_safe(row, col):
queens[row] = col
if solve_util(row + 1):
return True
return False
queens = [-1] * n
result = []
solve_util(0)
return [ ["".join(row) for row in board] for board in result]
This Python code provides a slightly simplified implementation focusing on readability. The other provided languages follow a similar structure, utilizing the three arrays for efficient conflict detection. Note that the exact constant factors within the time complexity might vary between implementations, but the overall factorial behavior remains the same.