n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例:
输入:4
输出:[
[“.Q..”, // 解法 1
“…Q”,
“Q…”,
“..Q.”],
[“..Q.”, // 解法 2
“Q…”,
“…Q”,
“.Q..”]
]
解释: 4 皇后问题存在两个不同的解法。
提示:
皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。
解法一:回溯
class Solution:def solveNQueens(self, n: int) -> List[List[str]]:"""N queens backtrace with DP"""solves = []# Marks unavailable cols, diags and anti_diagscols = [False] * ndiags = [False] * (2 * n - 1)anti_diags = [False] * (2 * n - 1)def _cell_to_diag(row, col):"""The first diag is on top left"""return row + coldef _cell_to_anti_diag(row, col):"""The first anti_diag is on bottem left"""return n - row + col - 1def _queen(row, solve):"""Test every col of current row.Add valid to current solve then find cols in the next row."""if row > n - 1:solves.append(solve)returnfor col in range(n):idx1 = _cell_to_diag(row, col)idx2 = _cell_to_anti_diag(row, col)if not cols[col] and not diags[idx1] and not anti_diags[idx2]:# Drop a queen on i-th row then mark col, diag and anti_diagcols[col] = diags[idx1] = anti_diags[idx2] = True_queen(row + 1, solve + [col])# Revert col, diag and anti_diag when tracing-backcols[col] = diags[idx1] = anti_diags[idx2] = Falsedef _print_solves(solves):return [[('.' * col + 'Q' + '.' * (n - col - 1))for col in solve]for solve in solves]_queen(0, [])return _print_solves(solves)
相关题目
52. N皇后 II
只要给出解的数量即可
class Solution:def totalNQueens(self, n: int) -> int:def backtrack(row: int) -> int:if row == n:return 1else:count = 0for i in range(n):if i in columns or row - i in diagonal1 or row + i in diagonal2:continuecolumns.add(i)diagonal1.add(row - i)diagonal2.add(row + i)count += backtrack(row + 1)columns.remove(i)diagonal1.remove(row - i)diagonal2.remove(row + i)return countcolumns = set()diagonal1 = set()diagonal2 = set()return backtrack(0)
