从零学算法51
51.N 皇后
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例 1:
输入:n = 4
输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:
输入:n = 1
输出:[[“Q”]]
提示:
1 <= n <= 9
- 回溯:重点在于搜索时怎样更好地判断当前位置是否能放皇后,可放条件包含:不能同行,同列,同一斜线,而斜线又有两个方向。
- 由于不能同行,所以最终结果就是每一行上放一个皇后,不妨定义数组 queens,queens[r] = x 表示在第 r 行的下标 x 处放皇后
- 定义布尔数组 col,col[i] 表示第 i 列是否有皇后
- 判断是否在同一条斜线可以通过判断两个位置的行(row)列(col)相加或相减是否相等
- 比如 4x4 的棋盘,第1行第1个,第2行第2个,第3行第3个…,行 - 列都为 0
- 另一条斜线:第1行第4个,第2行第3个,第3行第2个…,行 + 列都等于 5
- 所以只要定义两个数组用来存放 r+c 和 r-c 就能判断某条斜线上是否有皇后
-
var solveNQueens = function(n) {// 递归时行递增来避免同行const dfs = (r) => {if(r === n){res.push(queens.map(c=>'.'.repeat(c) + 'Q' + '.'.repeat(n - c - 1)))return}for(let c = 0; c < n; c++){// 避免同列,同斜线if(col[c] || add.includes(r+c) || reduce.includes(r-c))continue;col[c] = trueadd.push(r+c)reduce.push(r-c)queens[r] = c dfs(r + 1)add.pop()reduce.pop()col[c] = false}}const res = []const queens = Array(n).fill(0)const col = Array(n).fill(false)const add = []const reduce = []dfs(0)return res;};