The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle.
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:
Input: 4 Output: [ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] ] Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.
八皇后问题扩展到N皇后,经典的回溯算法题。
解法:回溯Backtracking
Java:
public class Solution {
public List<List<String>> solveNQueens(int n) {
char[][] board = new char[n][n];
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
board[i][j] = '.';
List<List<String>> res = new ArrayList<List<String>>();
dfs(board, 0, res);
return res;
}
private void dfs(char[][] board, int colIndex, List<List<String>> res) {
if(colIndex == board.length) {
res.add(construct(board));
return;
}
for(int i = 0; i < board.length; i++) {
if(validate(board, i, colIndex)) {
board[i][colIndex] = 'Q';
dfs(board, colIndex + 1, res);
board[i][colIndex] = '.';
}
}
}
private boolean validate(char[][] board, int x, int y) {
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < y; j++) {
if(board[i][j] == 'Q' && (x + j == y + i || x + y == i + j || x == i))
return false;
}
}
return true;
}
private List<String> construct(char[][] board) {
List<String> res = new LinkedList<String>();
for(int i = 0; i < board.length; i++) {
String s = new String(board[i]);
res.add(s);
}
return res;
}
}
Python:
class Solution(object):
def solveNQueens(self, n):
"""
:type n: int
:rtype: List[List[str]]
"""
def dfs(curr, cols, main_diag, anti_diag, result):
row, n = len(curr), len(cols)
if row == n:
result.append(map(lambda x: '.'*x + "Q" + '.'*(n-x-1), curr))
return
for i in xrange(n):
if cols[i] or main_diag[row+i] or anti_diag[row-i+n]:
continue
cols[i] = main_diag[row+i] = anti_diag[row-i+n] = True
curr.append(i)
dfs(curr, cols, main_diag, anti_diag, result)
curr.pop()
cols[i] = main_diag[row+i] = anti_diag[row-i+n] = False
result = []
cols, main_diag, anti_diag = [False]*n, [False]*(2*n), [False]*(2*n)
dfs([], cols, main_diag, anti_diag, result)
return result
Python:
# For any point (x,y), if we want the new point (p,q) don't share the same row, column, or diagonal.
# then there must have ```p+q != x+y``` and ```p-q!= x-y```
# the former focus on eliminate 'left bottom right top' diagonal;
# the latter focus on eliminate 'left top right bottom' diagonal
# - col_per_row: the list of column index per row
# - cur_row:current row we are seraching for valid column
# - xy_diff:the list of x-y
# - xy_sum:the list of x+y
class Solution2(object):
def solveNQueens(self, n):
"""
:type n: int
:rtype: List[List[str]]
"""
def dfs(col_per_row, xy_diff, xy_sum):
cur_row = len(col_per_row)
if cur_row == n:
ress.append(col_per_row)
for col in range(n):
if col not in col_per_row and cur_row-col not in xy_diff and cur_row+col not in xy_sum:
dfs(col_per_row+[col], xy_diff+[cur_row-col], xy_sum+[cur_row+col])
ress = []
dfs([], [], [])
return [['.'*i + 'Q' + '.'*(n-i-1) for i in res] for res in ress]
C++:
class Solution {
public:
vector<vector<string> > solveNQueens(int n) {
vector<vector<string> > res;
vector<int> pos(n, -1);
solveNQueensDFS(pos, 0, res);
return res;
}
void solveNQueensDFS(vector<int> &pos, int row, vector<vector<string> > &res) {
int n = pos.size();
if (row == n) {
vector<string> out(n, string(n, '.'));
for (int i = 0; i < n; ++i) {
out[i][pos[i]] = 'Q';
}
res.push_back(out);
} else {
for (int col = 0; col < n; ++col) {
if (isValid(pos, row ,col)) {
pos[row] = col;
solveNQueensDFS(pos, row + 1, res);
pos[row] = -1;
}
}
}
}
bool isValid(vector<int> &pos, int row, int col) {
for (int i = 0; i < row; ++i) {
if (col == pos[i] || abs(row - i) == abs(col - pos[i])) {
return false;
}
}
return true;
}
};
类似题目:
[LeetCode] 52. N-Queens II N皇后问题 II