按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例 1:
输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:
输入:n = 1
输出:[["Q"]]function solveNQueens(n) {
const result = [];
// 用三个 Set 分别记录被占用的列、主对角线、副对角线
const cols = new Set();
const diag1 = new Set(); // row - col
const diag2 = new Set(); // row + col
// board 记录每一行皇后所在的列索引
const board = new Array(n);
function backtrack(row) {
// 递归终止:所有行都放完了
if (row === n) {
// 将 board 转换成题目要求的字符串数组格式
result.push(buildBoard(board));
return;
}
// 尝试当前行的每一列
for (let col = 0; col < n; col++) {
const d1 = row - col;
const d2 = row + col;
// 检查是否冲突
if (cols.has(col) || diag1.has(d1) || diag2.has(d2)) {
continue;
}
// 做选择
board[row] = col;
cols.add(col);
diag1.add(d1);
diag2.add(d2);
// 递归下一行
backtrack(row + 1);
// 撤销选择(回溯)
cols.delete(col);
diag1.delete(d1);
diag2.delete(d2);
// board[row] 下一轮会被覆盖
}
}
// 辅助函数:将 board 转为 ['Q..', '...'] 格式
function buildBoard(board) {
const result = [];
for (let i = 0; i < n; i++) {
const row = new Array(n).fill('.');
row[board[i]] = 'Q';
result.push(row.join(''));
}
return result;
}
backtrack(0);
return result;
}