-- 回溯 - hard 点击直达力扣
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例 1:
输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:
输入:n = 1
输出:[["Q"]]
本题题解为结合代码随想录视频讲解,结合自己理解做出。查看视频
当发现for循环嵌套解决不了时,就应该试试回溯
本题与先前做的组合、排列、子集、分割问题不同的是,本题遍历是一个二维数组
如果在脑海中想出了树形结构,结合回溯,应该可以解出
let result = []
function solveNQueens(n: number): string[][] {
result = []
let queensArr = new Array(n).fill([]).map(() => new Array(n).fill('.'))
backTracking(queensArr, n, 0)
return result
};
// 用于回溯判断每一种情况,获取正确结果
// queensArr:存放结果集;n:共几行;row:当前遍历到第几行。
function backTracking(queensArr: string[][], n: number, row: number): void {
if (n === row) {
result.push(transform(queensArr))
return
}
for (let i = 0; i < n; i++) {
if (isValid(queensArr, n, row, i)) {
queensArr[row][i] = 'Q'
backTracking(queensArr, n, row + 1)
queensArr[row][i] = '.'
}
}
}
// 用于判断某数组是否满足n皇后的游戏规则
function isValid(queensArr: string[][], n: number, row: number, col: number): boolean {
// 判断同一列上有没有Q
for (let i = 0; i < row; i++) {
if (queensArr[i][col] === 'Q') { return false }
}
// 判断-45°角上有没有Q
for (let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (queensArr[i][j] === 'Q') { return false }
}
// 判断45°角上有没有Q
for (let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
if (queensArr[i][j] === 'Q') { return false }
}
return true
}
// 处理结果数组
function transform(queensArr) {
let queensArrBack = []
queensArr.forEach(row => {
let rowStr = ''
row.forEach(value => {
rowStr += value
})
queensArrBack.push(rowStr)
})
return queensArrBack
}