LeetCode - 51. N皇后

问题描述:

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。

每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

输入: 4
输出: [
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。

思路:

这道题简单来说,就是深度搜索,但是如果是想要来个最简单的遍历深搜的话,然后一步步判断目前的结果是否满足n皇后的话,一定会超时。所以我们要先理解好n皇后,先摆放的位置怎么去影响下一步摆放的位置选择。

如下图是八皇后,我们逐行进行位置的选择,首先我们第一行选择个‘4’(画的比较丑,就随意接受)

那第二行的时候,不能选的当然就是点(0,4)的正下、左斜下、右斜下,而且移动范围都是1或根号2。然后其他的点我们都可以选。

假设我们第二行选了6,那我们把目前选择的情况用列表写出来就是 [ 4 , 6 ]

我们现在要考虑的是第三行.第三行与第一行的距离是2,所以受到第一行选取的点(4)的影响,其正下、左斜下、右斜下,而且移动范围都是2或2倍根号2,也就是不能选2、4、6。同理,第三行与第二行的距离是1,所以受到第而行选取的点(6)的影响,其正下、左斜下、右斜下,而且移动范围都是1或1倍根号2,也就是不能选5、6、7。那就是说第三行能选择的点就只有0、1、3。

除了这个之外,就是正常深搜罢了,其实这一步就是给深搜树进行一定规则的剪枝。

代码:

class Solution:
    def __init__(self):
        self.put = []

    def kill(self,n,key,ceng):
        # n n皇后
        # key 目前每一行选择的数字
        # ceng 要判断的是第几行
        # 告诉你第ceng行可以还选哪些数字 并返回
        lo = [1 for i in range(n)]
        for i in range(len(key)):
            lo[key[i]]=0
            if key[i] - (ceng - i)>=0:
                lo[key[i] - (ceng - i)] = 0
            if key[i] + (ceng - i)<n:
                lo[key[i] + (ceng - i)] = 0
        res = []
        for i in range(n):
            if lo[i]==1:
                res.append(i)
        return res

    def show(self,n,key):
        # 根据传进来的key(每一行选择的数字)生成字符矩阵格式
        di = [['.'for i in range(n)] for j in range(n)]
        for i in range(n):
            di[i][key[i]]='Q'
        res = []
        for i in range(n):
            a=''
            for j in range(n):
                a+=di[i][j]
            res.append(a)
        return res

    def shen(self,n,key,ceng):
        # 深度搜索
        if ceng == n:
            # 能够达到层数说明完全符合条件
            self.put.append(key)
            # 可能的情况+1
            return 1
        res = 0
        # 遍历下一层所有的情况
        for i in self.kill(n,key,ceng):
            res += self.shen(n,key+[i],ceng+1)
        return res

    def solveNQueens(self, n):
        # res为n皇后的可能情况数,也就是52题的答案
        res = self.shen(n,[],0)
        put = []
        for i in self.put:
            put.append(self.show(n,i))
        # print(put)
        return put

if __name__ == '__main__':
    A = Solution()
    print(A.solveNQueens(4))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值