leetcode 51 52:N皇后问题位运算

本文介绍了一种使用位运算解决N皇后问题的方法,通过记录每一列及斜线上的皇后位置来减少空间复杂度,实现高效求解。文章提供了具体算法流程及代码实现。

题目描述:
51和52题是在给出N的时候,分别求出解的个数以及打印出各个解。
可以利用位运算解决N皇后问题。
主要思路:
与深度优先搜索+回溯的方式一致,只是在进行判断是否合理等一些细节上,选择利用位运算的方式进行处理。
利用位运算记录皇后的信息,就可以将记录皇后信息的空间复杂度从 O(N) 降到 O(1)。
具体做法是,使用三个整数 columns、diagonals_1和diagonals_2
​分别记录每一列以及两个方向的每条斜线上是否有皇后,每个整数有 N 个二进制位。棋盘的每一列对应每个整数的二进制表示中的一个数位,其中棋盘的最左列对应每个整数的最低二进制位,最右列对应每个整数的最高二进制位。
用 00 代表可以放置皇后的位置,11 代表不能放置皇后的位置。
三个整数的计算方法及具体的流程详见代码,一定要记住这个流程

class Solution:
    def totalNQueens(self, n: int) -> int:
        if n < 1:
            return []
        self.count = 0
        self.dfs(0, 0, 0, 0, n)
        return self.count

    def dfs(self, row, col, pie, na, n):
        if row >= n:
            self.count += 1
            return
        bits = ~(col | pie | na) & ((1 << n)-1)  # 本来是0可以为放置的位置,现在改为1,因为不然的话取非之后,前面全是1(这样做的的主要目的是只要后n位中可以放置的部分,不然的话前面全是0无法判断是否是可以放皇后的位置)
        while bits > 0:
            p = bits & -bits
            self.dfs(row+1, col | p, (pie | p) << 1, (na | p) >> 1, n)
            bits = bits & (bits - 1)

对于51题中,要把N皇后的每一个解都打印出来的问题,只需要申请一个数组,利用这个数组保存每一行放置的位置,之后按照每行放置的位置按照要求打印出来即可,代码如下:

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        def generateBoard():   # 这里是对解按照格式进行打印的方式,很简洁可以学习一下
            board = list()
            for i in range(n):
                row[queens[i]] = "Q"
                board.append("".join(row))
                row[queens[i]] = "."
            return board

        def solve(row: int, columns: int, diagonals1: int, diagonals2: int):
            if row == n:
                board = generateBoard()
                solutions.append(board)
            else:
                availablePositions = ((1 << n) - 1) & (~(columns | diagonals1 | diagonals2))
                while availablePositions:
                    position = availablePositions & (-availablePositions)
                    availablePositions = availablePositions & (availablePositions - 1)
                    column = bin(position - 1).count("1")
                    queens[row] = column  # 注意这里获得二进制对应位置的代码
                    solve(row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1)

        solutions = list()
        queens = [-1] * n
        row = ["."] * n
        solve(0, 0, 0, 0)
        return solutions

复杂度分析
时间复杂度:O(N!),其中 N 是皇后数量。
空间复杂度:O(N),其中 N 是皇后数量。由于使用位运算表示,因此存储皇后信息的空间复杂度是 O(1),空间复杂度主要取决于递归调用层数,递归调用层数不会超过 N。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值