n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
题目链接leetcode-cn.com/problems/n-…
解题思路:递归
还是那句话,遇事不决先递归
先来分析一下问题
先来分析一个给出的4x4的实例
我们把每一个位置放置Q的情况做分析
很明显,首先每一行只能放一个Q,而且放完以后会在后面的每一行产生3个不能放置Q的点(产生的点可以超出棋盘)如图所示:蓝色的线为该点向左产生的不能放置的Q点,黄色向右,绿色向下
首先我们定义一个变量,记录放置Q的点
path = [path1,path2,...]
那我们就可以针对这个不能放置Q的点定义一个变量pos = [[],[],[]],里面由三个数产生,分别是向下的向左的和向右的我们定义为l,r,m ,由于这个m是和path重复的这个变量我们就重新定义为
所有蓝线覆盖的点 l = [l1,l2,...]
所有黄线覆盖的点 r = [r1,r2,...]
和
所有线覆盖的点 total = [path + l + r]
这样我们就可以针对每个位置写判断的代码了,如果total里面没有该位置,我们就可以进入下一步,生成新的下一个行的l,r,total,
设当前执行的的行数为第n行,总行数为N
ln = [path1-(n-1),path2-(n-2),...]
rn = [path1+(n-1),path2+(n-2),...]
pathn = [path1,paht2,...]
我们就可以从第n行的0,开始判断
for i in range(N):
if i in total:
continue#没有空位就继续,
#有空位就进坑,使用这个位置进行下一行的递归
faction ([pathn]+[i],[ln]+[i],[rn]+[i])
算上上面的逻辑,我们就有这样的递归函数
def recursion(path, l , r):
if len(path) == n:#最后一行结束,如果是棋盘能放下最后一个
#这里要放一个记录下当前解法的代码
return
l = [i-1 for i in l]
r = [i+1 for i in r]
total = l+r+path
for i in range(n):
if i in total:
continue
recursion(path+[i], l+[i], r+[i])
再根据题目需求,把path改成题目需求的输出格式,整个题目的回答就是这样的
class Solution(object):
def solveNQueens(self, n):
"""
:type n: int
:rtype: List[List[str]]
"""
self.res = []
def trans(path):
return ['.'*i + 'Q' + '.'*(len(path)-1-i) for i in path]
def recursion(path, l , r):
if len(path) == n:
self.res.append(trans(path))
return
l = [i-1 for i in l]
r = [i+1 for i in r]
total = l+r+path
for i in range(n):
if i in total:
continue
recursion(path+[i], l+[i], r+[i])
recursion([], [], [])
return self.res