八皇后问题
https://leetcode-cn.com/problems/eight-queens-lcci/
描述
八皇后。设计一种算法,打印八皇后在8 × 8棋盘上的各种摆法,其中每个皇后都不同行、不同列,也不在对角线上。这里的“对角线”指的是所有的对角线,不只是平分整个棋盘的那两条对角线。
示例:
输入:4
输出:2
解释: 皇后问题存在如下两个不同的解法。
[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解法思路
这道问题关键在与:在按行放置皇后时,如何快速确定是否有两个皇后存在一个同一列, 同一对角线以及反对角线上
在同一列上, 很简单具有相同的列号, 使用set()
管理已经放置的列,既可在O(1)
的时间内确定是否有两个皇后在同一列上.
在同一对角线上, 更具对角线房产, y = x + k
, 可以发现, 两个皇后在同一对角线上的充要条件时: y1 - x1 = y2 - x2
. 使用set()
管理已经出现过的y-x
,既可在O(1)
的时间内确定是否有两个皇后在同一对角线上.
在同一反对角线上, 更具反对角线房产, y + x = k
, 可以发现, 两个皇后在同一对角线上的充要条件时: y1 + x1 = y2 + x2
. 使用set()
管理已经出现过的y+x
,既可在O(1)
的时间内确定是否有两个皇后在同一反对角线上
代码
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
dia, rdia, col, ans, cur = set(), set(), set(), [], [0] * n
def run(row):
nonlocal dia, col, ans
if row == n:
xx = [['.'] * n for _ in range(n)]
for i in range(n):
xx[i][cur[i]] = 'Q'
xx = [''.join(i) for i in xx]
ans.append(xx)
return
for i in range(n):
if row - i in dia or i in col or row + i in rdia: continue
cur[row] = i
dia.add(row - i)
rdia.add(row + i)
col.add(i)
run(row + 1)
dia.remove(row - i)
col.remove(i)
rdia.remove(row + i)
run(0)
return ans