方法1:visit二维数组
1、一行作为一层递归,本层for循环代表着本行的皇后的每个可能位置
2、用一个二维的visit数组存储皇后的攻击范围
3、放入一个皇后时,更新visit数组,回溯时,也更新visi数组
4、更新操作为“计数”,当计数为0时,该位置无攻击,当计数>0时,该位置有皇后攻击
5、计数不能为负
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
res = []
path = []
cantvisit_matrix = [[0] * n for _ in range(n)]
def set_cant(line, column):
for i in range(n):
cantvisit_matrix[line][i] += 1
cantvisit_matrix[i][column] += 1
for i in range(n):
for j in range(n):
if i - j == line - column:
cantvisit_matrix[i][j] += 1
if i + j == line + column:
cantvisit_matrix[i][j] += 1
def resvoca_cant(line, column):
for i in range(n):
if cantvisit_matrix[line][i] > 0:
cantvisit_matrix[line][i] -= 1
if cantvisit_matrix[i][column] > 0:
cantvisit_matrix[i][column] -= 1
for i in range(n):
for j in range(n):
if i - j == line - column:
if cantvisit_matrix[i][j] > 0:
cantvisit_matrix[i][j] -= 1
if i + j == line + column:
if cantvisit_matrix[i][j] > 0:
cantvisit_matrix[i][j] -= 1
def backtracking(line):
if line == n:
res.append(path[:])
return
for j in range(n):
if cantvisit_matrix[line][j] != 0:
continue
s = ['.'] * n
s[j] = 'Q'
path.append(''.join(s))
set_cant(line, j) #设置cant
backtracking(line+1)
resvoca_cant(line, j) #回溯cant
path.pop()
backtracking(0)
return res
方法2:直接验证棋盘
注意收集结果棋盘的时候,一定是一行一行去拷贝,因为如果你直接拷贝整个二维棋盘,每一行是一个列表(可变),这种浅拷贝是共享内存,会导致后续对棋盘的修改影响res。如果一行一行拷贝,每一行内是字符,字符不可变,所以不共享内存,创造的是副本。
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
res = []
chessborad = [['.'] * n for _ in range(n)]
def is_valid(row, col):
#检查同列
for i in range(row):
if chessborad[i][col] == 'Q':
return False
#左上
i = row - 1
j = col - 1
while i >= 0 and j >= 0:
if chessborad[i][j] == 'Q':
return False
i -= 1
j -= 1
#右上
i = row - 1
j = col + 1
while i >= 0 and j <= n-1:
if chessborad[i][j] == 'Q':
return False
i -= 1
j += 1
return True
def backtracking(row):
if row == n:
res.append([row_[:] for row_ in chessborad])
return
for col in range(n):
if not is_valid(row, col):
continue
chessborad[row][col] = 'Q'
backtracking(row+1)
chessborad[row][col] = '.'
backtracking(0)
res = [["".join(row) for row in solution] for solution in res]
return res