LeetCode 51.N皇后问题
题目分析
经典暴力枚举问题
问题主要在于如何处理避免皇后互相攻击(皇后可以攻击同一行、列以及同一左斜线、右斜线)。通过搜索行来避免行冲突,列用数组标记列号来避免列冲突。左斜线和右斜线比较难表示。
从图中可以看出,在同一左斜线上行标减去列标数值相同;在同一右斜线上行标加列标数值相同。因此用两个长度为2n的数组分别标记 r -c + n(加n用来变成正值) 和 r + c 来避免双斜线冲突。然后就是标准的暴力枚举了。
代码
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
global ans, rows, book1 ,book2, book3
book1 = [False for _ in range(n)]
book2 = [False for _ in range(2 * n)]
book3 = [False for _ in range(2 * n)]
rows = [0 for _ in range(n)]
ans = []
def dfs(r, n):
if r >= n:
G = []
for c in rows:
G.append('.' * c + 'Q' + '.' * (n - c - 1))
ans.append(G)
return
for i in range(n):
if not book1[i] and not book2[r - i + n] and not book3[i + r]:
book1[i] = book2[r - i + n] = book3[i + r] = True
rows[r] = i
dfs(r + 1, n)
book1[i] = book2[r - i + n] = book3[i + r] = False
dfs(0, n)
return ans
ps: 时间上击败了99%,有点意外。