• 51N皇后


    题目:皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
    来源:https://leetcode-cn.com/problems/n-queens/

    法一: 自己的代码   时间超过了百分之90

    思路: 参照官方的解法,用处理list的回溯框架实现了一遍,关键是要满足题中的四个条件,水平的是用for循环遍历的,不会出现重复,两个斜向的用p和q来实现,竖直方向用cols来记录,这四个条件实际上就是剪枝条件.

    class Solution:
        def solveNQueens(self, n: int):
            results = []
            def backtrack(row=-1,col=0):
                # 回溯终止条件,如果到最后一行了,说明找到一个解了,存储
                if row == n-1:
                    solution = []
                    for _, col in sorted(queens):
                        solution.append('.' * col + 'Q' + '.' * (n - col - 1))
                    results.append(solution)
                    return
                row += 1
                for col in range(n):
                    # 如果等于0,说明可以放,
                    # if这儿就是剪枝条件
                    if cols[col] + p[col+row] + q[col-row] == 0:
                        # 放置一个皇后
                        queens.add((row,col))
                        # 这里cols的作用实际上是为了记录竖直方向上是否偶皇后,
                        # p,q为了记录两个斜方向上是否有皇后
                        # 水平方向用for循环遍历,每次回溯结束后就置0,所以一定没有皇后
                        # 且由于这些都是可变对象,回溯函数每次调用结束后,值更改后的值仍然存在,故需要回溯函数后面加上置0的程序
                        # 而 row 和 col是不变对象,回溯函数每次调用结束后,会恢复调用前的值
                        cols[col] = 1
                        p[col+row] = 1
                        q[col-row] = 1
                        backtrack(row,col)
                        # 回溯函数结束后,取出刚才放的皇后,继续for循环,判断下一个位置
                        queens.remove((row,col))
                        cols[col] = 0
                        p[col + row] = 0
                        q[col - row] = 0
            cols = [0] * n
            # p记录主对角线方向的,q记录副对角线方向的
            # p,q是通过画图观察出来的,引入p,q是为了区分放置皇后后斜线方向上不能再放置皇后
            p = [0] * (2*n - 1)
            q = [0] * (2*n - 1)
            # 因为list不能append pop 元组,故这里用set
            queens = set()
            backtrack()
            return results
    if __name__ == '__main__':
        duixiang = Solution()
        ww = duixiang.solveNQueens(4)
        print('结果是:', ww)
    View Code

    法二: 官方的解法,思路非常清晰用了多个函数实现了模块化

    # 官网python代码
    class Solution:
        def solveNQueens(self, n: int):
            def could_place(row, col):
                return not (cols[col] + hill_diagonals[row - col] + dale_diagonals[row + col])
            def place_queen(row, col):
                queens.add((row, col))
                cols[col] = 1
                hill_diagonals[row - col] = 1
                dale_diagonals[row + col] = 1
            def remove_queen(row, col):
                queens.remove((row, col))
                cols[col] = 0
                hill_diagonals[row - col] = 0
                dale_diagonals[row + col] = 0
            def add_solution():
                solution = []
                for _, col in sorted(queens):
                    solution.append('.' * col + 'Q' + '.' * (n - col - 1))
                output.append(solution)
            def backtrack(row=0):
                for col in range(n):
                    if could_place(row, col):
                        place_queen(row, col)
                        if row + 1 == n:
                            add_solution()
                        else:
                            backtrack(row + 1)
                        # 执行这个的目的是回溯函数结束时,返回调用前的状态
                        remove_queen(row, col)
            cols = [0] * n
            hill_diagonals = [0] * (2 * n - 1)
            dale_diagonals = [0] * (2 * n - 1)
            queens = set()
            output = []
            backtrack()
            return output
    if __name__ == '__main__':
        duixiang = Solution()
        ww = duixiang.solveNQueens(4)
        print('结果是:', ww)
    View Code
  • 相关阅读:
    第二次冲刺阶段第四天
    第二次冲刺阶段第三天
    第二次冲刺阶段第二天
    人月神话阅读笔记03
    第二次冲刺阶段第一天
    学习进度条(十二)
    课堂练习-找水王
    学习进度条(十一)
    学习进度表第十周
    构建之法阅读笔记06
  • 原文地址:https://www.cnblogs.com/xxswkl/p/11968132.html
Copyright © 2020-2023  润新知