N 皇后问题是指在 n * n 的棋盘上要摆 n 个皇后,
要求:任何两个皇后不同行,不同列也不在同一条斜线上,
求给一个整数 n ,返回 n 皇后的摆法数。
要求:任何两个皇后不同行,不同列也不在同一条斜线上,
求给一个整数 n ,返回 n 皇后的摆法数。
数据范围:
要求:空间复杂度
,时间复杂度
例如当输入4时,对应的返回值为2,
对应的两种四皇后摆位如下图所示:
# # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param n int整型 the n # @return int整型 # class Solution: def isValid(self, row, col, dp, n): # 检查同一列是否有相同的 for i in range(row): if dp[i][col] == "Q": return False # 判断45°角 i, j = row - 1, col - 1 while i >= 0 and j >= 0: if dp[i][j] == "Q": return False i -= 1 j -= 1 # 判断135°角 i, j = row - 1, col + 1 while i >= 0 and j < n: if dp[i][j] == "Q": return False i -= 1 j += 1 return True def backtracking(self, n, row, dp): if row == n: self.res += 1 return for col in range(n): if self.isValid(row, col, dp, n): dp[row][col] = "Q" self.backtracking(n, row + 1, dp) dp[row][col] = "." def Nqueen(self, n: int) -> int: # write code here self.res = 0 dp = [["."] * n for _ in range(n)] self.backtracking(n, 0, dp) return self.res
class Solution: # 判断当前坐标能不能放Q def __isOk(self, i, j, coords): for (row, col) in coords: # 同一行 if i == row: return False # 同一列 if j == col: return False # 斜对角 if i + j == row + col: return False if i - j == row - col: return False return True def __dfs(self, n:int, k:int, coords): if k == n: self.count += 1 return for i in range(n): if self.__isOk(k, i, coords): coords.append((k, i)) self.__dfs(n, k+1, coords) # 恢复状态 coords.pop() def Nqueen(self , n: int) -> int: # write code here self.count = 0 # 定义一个2*n的数组用来记录所有放Q的坐标 coords = [] # 从第一层开始遍历 self.__dfs(n, 0, coords) return self.count
class Solution: #判断皇后是否符合条件 def isValid(self, pos: List[int], row:int, col:int): # row为当前要放置皇后的行,col当前要摆放皇后的位置 # 遍历之前所有行,皇后的所在位置 for i in range(row): #不能同行同列同一斜线 # 不能同列:col == pos[i] 判断当前位置,与之前行位置的皇后是否在同一位置 # 不能同对角线:abs(row - i) == abs(col - pos[i]) 判断当前位置是否与之前的皇后在同一对角线上 if col == pos[i]&nbs***bsp;abs(row - i) == abs(col - pos[i]): return False return True #递归查找皇后种类 def recursion(self, n:int, row:int, pos:List[int], res:int): #完成全部行都选择了位置 if row == n: res += 1 return int(res) # 每行遍历所有可能 for i in range(n): #检查该位置是否符合条件 if self.isValid(pos, row, i): #加入位置 pos[row] = i #递归继续查找 res = self.recursion(n, row + 1, pos, res) return res def Nqueen(self , n: int) -> int: res = 0 # pos[i],i为第几行,pos[i]表示第i行的皇后放的位置,pos[3] = 7 第4行的皇后在第7位置 pos = [0] * n # 递归 result = self.recursion(n, 0, pos, res) return result
class Solution: def is_vaild(self, row, col, pos): for i in range(row): if row == i or col == pos[i] or abs(row-i) == abs(col-pos[i]): return False return True def recursion(self, pos, res, row, n): if row == n: res += 1 return res for i in range(n): if self.is_vaild(row, i, pos): pos[row] = i res = self.recursion(pos, res, row+1, n) return res def Nqueen(self , n: int) -> int: pos = [0] * n res = 0 result = self.recursion(pos, res, 0, n) return result
DFS
# # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param n int整型 the n # @return int整型 # class Solution: def Nqueen(self , n: int) -> int: # write code here ret = [1, 0, 0] if n <= 3: return ret[n - 1] # book[i] = j 表示第 i 行的“皇后”放在了第 j 列 book = [-1] * n def valid(i, j): """验证当前点 (i,j) 与所有已经放置的点 (i_,j_) 是否共列或共斜线""" for i_ in range(i): j_ = book[i_] # 如果共列或共斜线,因为 i_ < i,所以不会共行 if j == j_ or abs(i - i_) == abs(j - j_): return False return True def dfs(i): """深度优先遍历每一行""" if i == n: # 找到一种摆法 return 1 ret = 0 for j in range(n): # 遍历第 i 行的每个点 (i, j) if valid(i, j): # 验证当前点 (i, j) 是否能放 book[i] = j ret += dfs(i + 1) # book[i] = -1 # 这里不需要回溯,因为 valid 只会遍历 book[0:i-1] return ret return dfs(0)