zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    php记录代码执行时间
    java中针对同一变量的不同函数的互斥操作
    Linux下mysql新建账号及权限设置
    Linux下重启apache
    Mysql数据导入
    ubuntu安装phpcurl与phptidy扩展
    Linux服务器间文件传输
    Flash本地传递大数据,图片数据,localconnection 超出大小,超出限制 bitmapdata 拂晓风起
    [Java][JavaScript]字符串数组与字符串之间的互转(join/split)(转) 拂晓风起
    java poi读取excel公式,返回计算值(转) 拂晓风起
  • 原文地址:https://www.cnblogs.com/xxswkl/p/11968132.html
Copyright © 2011-2022 走看看