八皇后问题

https://leetcode-cn.com/problems/eight-queens-lcci/

描述

八皇后。设计一种算法,打印八皇后在8 × 8棋盘上的各种摆法,其中每个皇后都不同行、不同列,也不在对角线上。这里的“对角线”指的是所有的对角线,不只是平分整个棋盘的那两条对角线。

示例:

输入:4

输出:2

解释: 皇后问题存在如下两个不同的解法。

[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],

["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]

解法思路

这道问题关键在与:在按行放置皇后时,如何快速确定是否有两个皇后存在一个同一列, 同一对角线以及反对角线上

在同一列上, 很简单具有相同的列号, 使用set()管理已经放置的列,既可在O(1)的时间内确定是否有两个皇后在同一列上.

在同一对角线上, 更具对角线房产, y = x + k, 可以发现, 两个皇后在同一对角线上的充要条件时: y1 - x1 = y2 - x2. 使用set()管理已经出现过的y-x,既可在O(1)的时间内确定是否有两个皇后在同一对角线上.

在同一反对角线上, 更具反对角线房产, y + x = k, 可以发现, 两个皇后在同一对角线上的充要条件时: y1 + x1 = y2 + x2. 使用set()管理已经出现过的y+x,既可在O(1)的时间内确定是否有两个皇后在同一反对角线上

代码

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        dia, rdia, col, ans, cur = set(), set(), set(), [], [0] * n
        def run(row):
            nonlocal dia, col, ans
            if row == n: 
                xx = [['.'] * n for _ in range(n)]
                for i in range(n):
                    xx[i][cur[i]] = 'Q'
                xx = [''.join(i) for i in xx]
                ans.append(xx)
                return
            for i in range(n):
                if row - i in dia or i in col or row + i in rdia: continue
                cur[row] = i
                dia.add(row - i)
                rdia.add(row + i)
                col.add(i)
                run(row + 1)
                dia.remove(row - i)
                col.remove(i)
                rdia.remove(row + i)
        run(0)
        return ans
posted @ 2020-02-13 21:30  CYHua  阅读(151)  评论(0编辑  收藏  举报