这道题面试的时候问到了,hard程度的题啊,没做过真的想不出来的,所以说还是要刷题,每天刷会有感觉的。(做这道题哭liao,明天再做一遍吧)
1. 题目描述
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
即不能在同一行、同一列、同一对角线、同一逆对角线。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q…", // 解法 1
“…Q”,
“Q…”,
“…Q.”],
["…Q.", // 解法 2
“Q…”,
“…Q”,
“.Q…”]
]
解释: 4 皇后问题存在两个不同的解法。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-queens
2. 解题思路
(1). 确定皇后的攻击范围(五角星表示皇后放的位置,红色的表示皇后的攻击范围)
(2). 回溯思路
核心方法是判断指定row和col能否放,能放就递归row+1的所有列,不能放就回溯。
如下图所示:
3. 代码实现
class Solution(object):
def solveNQueens(self, n):
board, ret = [['.'] * n for _ in range(n)], []
self.dfs(board, n, 0, ret)
return ret
def dfs(self, board, n, row, ret):
if row == n:
ret.append(["".join(i) for i in board])
return
#核心方法是判断指定row和col能否放,能放就递归row+1的所有列,不能放就回溯
for i in range(n):
if not self.canPlace(row, i, n, board):
continue
board[row][i] = 'Q'
self.dfs(board, n, row + 1, ret)
board[row][i] = '.'
#判断当前情况下能否放置皇后
def canPlace(self, row, col, n, board):
for i in range(1, row + 1):
# 判断同一列上是否有Q
if board[row - i][col] == 'Q':
return False
# 判断逆对角线是否有Q
if col - i >= 0 and board[row - i][col - i] == 'Q':
return False
# 判断正对角线是否有Q
if col + i < n and board[row - i][col + i] == 'Q':
return False
return True