经典的N-Queens问题找到了一种在n×n棋盘上放置n个皇后的方法,这样就不会有两个皇后互相攻击。 这是我对N-Queens问题的解决方案。
class Solution(object):
def solveNQueens(self, n):
"""
:type n: int
:rtype: List[List[str]]
"""
grid = [['.' for _ in range(n)] for _ in range(n)]
solved = self.helper(n, 0, grid)
if solved:
return ["".join(item) for item in grid]
else:
return None
def helper(self, n, row, grid):
if n == row:
return True
for col in range(n):
if self.is_safe(row, col, grid):
grid[row][col] = 'Q'
if self.helper(n, row + 1, grid):
return True
else:
grid[row][col] = '.'
return False
def is_safe(self, row, col, board):
for i in range(len(board)):
if board[row][i] == 'Q' or board[i][col] == 'Q':
return False
i = 0
while row - i >= 0 and col - i >= 0:
if board[row - i][col - i] == 'Q':
return False
i += 1
i = 0
while row + i < len(board) and col + i < len(board):
if board[row + i][col - i] == 'Q':
return False
i += 1
i = 1
while row + i < len(board) and col - i >= 0:
if board[row + i][col - i] == 'Q':
return False
i += 1
i = 1
while row - i >= 0 and col + i < len(board):
if board[row - i][col + i] == 'Q':
return False
i += 1
return True
if __name__ == '__main__':
solution = Solution()
print(solution.solveNQueens(8))
此问题的扩展说明,找到所有可能的解决方案并以列表的形式返回它们。 我试图通过向helper方法添加一个列变量来扩展我的解决方案,该方法从0开始,以跟踪一个完整的解决方案和下一个的开始。 因此,基本情况变为
if row == n and col == n:
return True
但是这种方法不起作用,因为每个连续的递归调用都会在错误的列中结束。 有人可以帮助扩展此解决方案以找到所有可能的解决方案。
答案 0 :(得分:4)
好问题! N-queens也是一个很好的递归问题:)你实际上非常接近得到你想要的东西,而你不必过多地修改你的代码。
考虑这个问题的好方法是了解您正在考虑的两个不同问题。您当前的方法是使用回溯来找到第一个解决方案。您要做的是找到所有解决方案,类似的问题只需要您以不同的方式考虑您的基本情况。
在当前设置中,如果您的基本情况返回True,则父呼叫将短路并返回True。这是尝试找到任何单一解决方案的理想选择,因为一旦我们发现一个有效的解决方案,我们知道我们可以停止寻找。但是,因此,我们不会继续探索其他途径。
考虑回溯的一种方法是,你基本上是在创建一个由可能的移动产生的可能板的树。要找到第一个解决方案,只要到达叶节点或获胜状态,就会一直返回。但是,您要做的是继续遍历树的所有其他路径,并继续寻找叶子获胜状态并沿途记录它们。
因此,修改当前方法的一种简单方法是修改基本情况,以便不是返回True,而是在跟踪所有解决方案的变量中记录板的状态,获胜状态。另外,现在在你的递归情况下,当你进行递归调用时,你不会检查它是返回True还是False,而是继续在for循环中继续并尝试所有移动。
我修改了你的解决方案,得到了92个解决方案,互联网确认这是真的:)
class Solution(object):
def __init__(self):
self.solutions = []
def solveNQueens(self, n):
"""
:type n: int
:rtype: List[List[str]]
"""
grid = [['.' for _ in range(n)] for _ in range(n)]
solved = self.helper(n, 0, grid)
print len(self.solutions)
if solved:
return ["".join(item) for item in grid]
else:
return None
def helper(self, n, row, grid):
if n == row:
print "wooo"
self.solutions.append(copy.deepcopy(grid))
return
for col in range(n):
if self.is_safe(row, col, grid):
grid[row][col] = 'Q'
self.helper(n, row + 1, grid)
grid[row][col] = '.'
我希望这有帮助!