[Leetcode][python]N-Queens/N-Queens II/N皇后/N皇后 II

简介: N-Queens题目大意经典的八皇后问题的一般情况 注意点: 皇后用"Q"表示,空白用"."表示解题思路回溯法,位运算等,见总结


N-Queens



题目大意

经典的八皇后问题的一般情况 注意点: 皇后用"Q"表示,空白用"."表示


解题思路

回溯法,位运算等,见总结


代码


回溯法

使用一位数组存储可能的解法例如[1,3,0,2],最后再生成二位字符串图形

如图理解:

网络异常,图片无法展示
|

class Solution(object):
    def solveNQueens(self, n):
        """
        :type n: int
        :rtype: List[List[str]]
        """
        self.n = n
        result = []
        columns = [-1 for i in range(n)]  # [-1, -1, -1, -1]
        self.solve(columns, 0, result)
        return result
  # 绘出完整棋盘
    def make_string_list(self, columns):
        sol = []  # 一个完整的棋盘
        row = ['.' for i in range(self.n)]  # ['.', '.', '.', '.']
        for c in columns:
            new_row = row[:] 
            new_row[c] = 'Q'
            sol.append(''.join(new_row))  # 将row转为new_row, 将Q加入,然后转为字符串
        return sol
  # 判断是否符合要求
    def is_valid(self, columns, row, col):
        # print columns, 'hang', row, 'lie', col
        for r in range(row):
            c = columns[r]
            # print c, col
            if c == col:  # 在同一列,放弃
                return False
            if abs(c - col) == row - r:  # 对角线,放弃
                return False
        return True
    def solve(self, columns, row, result):
        if row == self.n:  # 所有列处理完毕
            # print 'columns:', columns # [1, 3, 0, 2], [2, 0, 3, 1]
            result.append(self.make_string_list(columns))
        else:
            for col in range(self.n):  # 依次遍历列,每个数字就代表每列皇后放在了第几行
                if self.is_valid(columns, row, col):
                    columns[row] = col
                    self.solve(columns, row + 1, result)
复制代码


位计算

解决思路还是一行一行地查找。但是使用3个2进制数来存储列、左对角线、右对角线上不能下棋的位置。

如下图所示(1表示位置不合法): [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0v7UDbv8-1615631437348)(github.com/zhsj/nqueen…)]

于是当前行所有不合法位置即为 row | ld | rd ,整体上加快了寻找合法位置的速度。


考虑问题的对称性

将8皇后其中一个解垂直翻转后,可以得到一个新的解,故,可以只计算一半,从而加快时间。


N-Queens II



题目大意

计算解的个数


解题思路

不需要画图,有一个解就自增1


代码

class Solution(object):
    def totalNQueens(self, n):
        """
        :type n: int
        :rtype: int
        """
        self.n = n
        self.result = 0
        columns = [-1 for i in range(n)]  # [-1, -1, -1, -1]
        self.solve(columns, 0, self.result)
        return self.result
    def is_valid(self, columns, row, col):
        # print columns, 'hang', row, 'lie', col
        for r in range(row):
            c = columns[r]
            # print c, col
            if c == col:  # 在同一列,放弃
                return False
            if abs(c - col) == row - r:  # 对角线,放弃
                return False
        return True
    def solve(self, columns, row, result):
        if row == self.n:  # 所有列处理完毕
            # print 'columns:', columns # [1, 3, 0, 2], [2, 0, 3, 1]
            self.result += 1
        else:
            for col in range(self.n):  # 依次遍历列,每个数字就代表每列皇后放在了第几行
                if self.is_valid(columns, row, col):
                    columns[row] = col
                    self.solve(columns, row + 1, result)
复制代码


总结


代码我都尽量详细注释,并且把重要变量print出来便于理解

经典回溯法问题,解法很多,不过无外乎递归非递归等。 看到用位计算的,以后学习参考,效率两道题目都是最高的。github.com/zhsj/nqueen…


相关文章
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
65 6
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
59 4
|
5月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
133 2
|
5月前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
79 7
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
61 5
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
36 4
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
Leetcode题目"剑指 Offer 21. 调整数组顺序使奇数位于偶数前面"的两种Python解决方案,一种是使用双端队列调整数组顺序,另一种是使用双指针法将奇数移到数组前半部分,偶数移到后半部分。
31 4
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 18. 删除链表的节点
Leetcode题目"剑指 Offer 18. 删除链表的节点"的Python解决方案,通过使用双指针法找到并删除链表中值为特定数值的节点,然后返回更新后的链表头节点。
48 4
|
5月前
|
算法 JavaScript Python
【Leetcode刷题Python】79. 单词搜索和剑指 Offer 12. 矩阵中的路径
Leetcode第79题"单词搜索"的Python解决方案,使用回溯算法在给定的二维字符网格中搜索单词,判断单词是否存在于网格中。
64 4
|
5月前
|
存储 Python
【Leetcode刷题Python】滑雪路径消耗时间:Testing Round #16 (Unrated) C. Skier
Leetcode题目"Testing Round #16 (Unrated) C. Skier"的Python解决方案,题目要求计算给定滑雪路径字符串的总耗时,其中未走过的边耗时5秒,走过的边耗时1秒。
60 4