不管全世界所有人怎么说,我都认为自己的感受才是正确的。无论别人怎么看,我绝不打乱自己的节奏。喜欢的事自然可以坚持,不喜欢的怎么也长久不了。
LeetCode:原题地址
题目要求
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例 1:
输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:
输入: n = 1
输出: [["Q"]]
思路
从上到下,从左到右遍历棋盘,准备好三个set分别记录列和两个对角线可以攻击到的坐标,尝试在每个空位放置皇后,放置之后更新三个可以攻击到的set坐标,然后继续下一层遍历,完成下一层之后,尝试回溯当前层,也就是撤销当前层放置的皇后,同时撤销三个可以攻击到的set坐标,不断回溯,直到遍历完成,找到所有可能的解。
/**
* @param {number} n
* @return {string[][]}
*/
const solveNQueens = (n) => {
const board = new Array(n);
for (let i = 0; i < n; i++) {
board[i] = new Array(n).fill('.');//生成board
}
const cols = new Set(); // 列集,记录出现过皇后的列
const diag1 = new Set(); // 正对角线集
const diag2 = new Set(); // 反对角线集
const res = [];//结果数组
const backtrack = (row) => {
if (row == n) {//终止条件
const stringsBoard = board.slice();
for (let i = 0; i < n; i++) {//生成字符串
stringsBoard[i] = stringsBoard[i].join('');
}
res.push(stringsBoard);
return;
}
for (let col = 0; col < n; col++) {
// 如果当前点的所在的列,所在的对角线都没有皇后,即可选择,否则,跳过
if (!cols.has(col) && !diag1.has(row + col) && !diag2.has(row - col)) {
board[row][col] = 'Q'; // 放置皇后
cols.add(col); // 记录放了皇后的列
diag2.add(row - col); // 记录放了皇后的正对角线
diag1.add(row + col); // 记录放了皇后的负对角线
backtrack(row + 1);
board[row][col] = '.'; // 撤销该点的皇后
cols.delete(col); // 对应的记录也删一下
diag2.delete(row - col);
diag1.delete(row + col);
}
}
};
backtrack(0);
return res;
};