题目描述
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例:
输入:4
输出:[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
提示:
皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。
解题思路
回溯法。每一行每一列以及对角线上有且只有一个皇后。n=4
第1行,皇后有4种选择。
第2行,皇后有3种选择。
第3行,皇后有2种选择。
第4行,皇后有1种选择。
同时,要保证每一种选择不会让皇后彼此相互攻击。即每一列,每一对角线和反对角线上有且仅有一个皇后。
参考代码
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
def generateBoard():
board = list()
for i in range(n):
row[queens[i]] = "Q"
board.append("".join(row))
row[queens[i]] = "."
return board
def backtrack(row:int):
if row == n:
board = generateBoard()
solutions.append(board)
else:
for i in range(n):
if i in columns or row - i in diagonal1 or row + i in diagonal2:
continue
queens[row] = i
columns.add(i)
diagonal1.add(row-i)
diagonal2.add(row+i)
backtrack(row+1)
columns.remove(i)
diagonal1.remove(row-i)
diagonal2.remove(row+i)
solutions = list()
queens = [-1] * n
columns = set() # 记录每一列有无皇后
diagonal1 = set() # 记录当前位置正对角线有无皇后
diagonal2 = set() # 记录当前位置斜对角线有无皇后
row = ["."] * n # 记录每一行皇后的位置
backtrack(0)
return solutions