递归/DFS/BFS
在不断更新中...
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例 1:
输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:输入:n = 1
输出:[["Q"]]
提示:
1 <= n <= 9
皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-queens
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
方法一:暴力搜索
这道题可以转换为求1~n这n个数的全排列的问题。暴力搜索列出1~n这n个数的所有排列,再判断排列是否满足n皇后的规则(不同行、不同列、不同对角线)
class Solution:
def generate_permutation(self, index):
if index == self.n:
flag = 1
for i in range(self.n):
for j in range(i + 1, self.n):
if abs(i - j) == abs(self.p_current[i] - self.p_current[j]): # 判断两个皇后是否位于同一对角线上
flag = 0
break
if flag:
# print(p_current)
self.permutation_list.append(self.p_current.copy())
self.count += 1
return
for i in range(self.n):
if self.num_exist[i] == 0:
# print(i + 1)
self.p_current[index] = i + 1
self.num_exist[i] = 1
self.generate_permutation(index + 1)
self.num_exist[i] = 0
def solveNQueens(self, n):
"""
:type n: int
:rtype: List[List[str]]
"""
self.n = n
self.num_exist = [0] * n # 记录某个数字是否已经存在在当前排列中
self.permutation_list = [] # 所有排列
self.p_current = [0] * n # 当前的排列
self.count = 0 # 合法的方案数
self.generate_permutation(0) # 生成符合n皇后规则的排列
result = []
k = 0
for each in self.permutation_list:
# print(each)
r = []
for i in range(n):
pp = ['.'] * n
pp[each[i] - 1] = 'Q'
r.append(''.join(pp))
k += 1
result.append(r)
return result
方法二:回溯法
同样是求1~n这n个数的排列,但是比起方法一是先求完了所有排列在一个个判断是否符合n皇后规则,我们可以发现,当放置了一部分皇后时,可能剩余的皇后无论怎么放都不会合法,此时没必要往下递归了,直接返回上一层,可以减少计算量,这就是回溯法。
class Solution:
def generate_permutation(self, index):
if index == self.n:
self.permutation_list.append(self.p_current.copy())
return
for i in range(self.n):
if self.num_exist[i] == 0:
flag = 1
for pre in range(0, index):
if abs(index - pre) == abs(i - self.p_current[pre] + 1):
flag = 0
break
if flag:
self.p_current[index] = i + 1
self.num_exist[i] = 1
self.generate_permutation(index + 1)
self.num_exist[i] = 0
def solveNQueens(self, n):
"""
:type n: int
:rtype: List[List[str]]
"""
self.n = n
self.num_exist = [0] * n # 记录某个数字是否已经存在在当前排列中
self.permutation_list = [] # 所有排列
self.p_current = [0] * n # 当前的排列
self.count = 0 # 合法的方案数
self.generate_permutation(0) # 生成符合n皇后规则的排列
result = []
k = 0
for each in self.permutation_list:
r = []
for i in range(n):
pp = ['.'] * n
pp[each[i] - 1] = 'Q'
r.append(''.join(pp))
k += 1
result.append(r)
return result
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回 n 皇后问题 不同的解决方案的数量。
示例 1:
输入:n = 4
输出:2
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:输入:n = 1
输出:1
提示:
1 <= n <= 9
皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-queens-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:求n皇后的排列的方法请看前一题,前一题可以得到n皇后的所有排列,这一题就是统计一下排列个数就可以了。
class Solution:
def generate_permutation(self, index):
if index == self.n:
# self.permutation_list.append(self.p_current.copy())
self.count += 1
return
for i in range(self.n):
if self.num_exist[i] == 0: