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
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The N-Queens problem asks us to place queens on a chessboard so that none can attack each other. The brute force method is like trying every single possible arrangement of queens on the board until you find one that works.
Here's how the algorithm would work step-by-step:
def solve_n_queens_brute_force(number_of_queens):
solutions = []
def is_safe(board_state, row_index, column_index):
for previous_row_index in range(row_index):
# Check same column
if board_state[previous_row_index] == column_index:
return False
# Check diagonals
column_distance = abs(board_state[previous_row_index] - column_index)
row_distance = row_index - previous_row_index
if column_distance == row_distance:
return False
return True
def find_all_arrangements(row_index, board_state):
# Base case: All queens are placed
if row_index == number_of_queens:
solutions.append(board_state[:])
return
for column_index in range(number_of_queens):
# Check if this position is safe
if is_safe(board_state, row_index, column_index):
board_state[row_index] = column_index
# Recursively try to place the next queen
find_all_arrangements(row_index + 1, board_state)
# Initialize the board state
board_state = [0] * number_of_queens
# Start the recursive process from the first row
find_all_arrangements(0, board_state)
return solutions
The N-Queens problem involves placing queens on a chessboard so that no two queens threaten each other. The optimal solution strategically places queens row by row, avoiding the need to explore invalid placements. It leverages a key insight: once a queen is placed, we know the squares that are no longer available.
Here's how the algorithm would work step-by-step:
def solve_n_queens(number_of_queens):
solutions = []
board_state = [0] * number_of_queens
def is_safe(row_index, column_index):
for previous_row_index in range(row_index):
previous_column_index = board_state[previous_row_index]
if previous_column_index == column_index:
return False
if abs(previous_column_index - column_index) == row_index - previous_row_index:
return False
return True
def find_solutions(row_index):
# Base case: All queens are placed.
if row_index == number_of_queens:
solutions.append(board_state[:])
return
# Try placing a queen in each column of the current row.
for column_index in range(number_of_queens):
if is_safe(row_index, column_index):
# Place the queen if the position is safe
board_state[row_index] = column_index
# Recursively find solutions for the next row.
find_solutions(row_index + 1)
# Backtrack: Remove the queen and try the next column.
find_solutions(0)
return solutions
Case | How to Handle |
---|---|
N is zero or negative | Return an empty list as there is no valid board configuration for non-positive N. |
N is equal to 1 | Return a list containing a single solution [['Q']] as a 1x1 board trivially allows placing one queen. |
N is 2 or 3 | Return an empty list, as no valid solution exists for N=2 or N=3 due to the queens being able to attack each other. |
Large N values (e.g., N > 12) | The backtracking algorithm's time complexity increases exponentially, potentially leading to stack overflow or timeout errors; consider iterative solutions or pruning optimizations. |
Integer overflow when calculating diagonals for very large N | Ensure data types used for diagonal calculations can handle large values, potentially using long or BigInteger if needed to prevent overflows. |
Multiple valid solutions exist | The backtracking algorithm should explore all possible valid placements and collect all distinct solutions in a result list. |
Memory exhaustion for large N due to storing all solutions | If memory is a constraint, consider alternative approaches like returning only the count of solutions, or generating solutions on demand without storing all of them simultaneously. |
Floating point errors with approximations of diagonals. | Ensure the code relies on integer arithmetic when calculating the positions of the diagonals, rather than relying on floating point computations. |