每天一道算法题:51. N 皇后

news2024/11/28 10:35:24

难度

困难

题目

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n_ _皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
queens.jpg

示例 1:

输入:n = 4
输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

示例 2:

输入:n = 1
输出:[[“Q”]]

提示:

1 <= n <= 9
皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。

思路

N 皇后问题是一个经典的回溯算法问题,要求在 N×N 的棋盘上放置 N 个皇后,使得它们互相不能攻击(即不能在同一行、同一列或同一斜线上),N 皇后问题的一种解题思路,采用回溯算法:

  1. 初始化一个 n * n的棋盘,默认都为0,表示未放棋,初始化三个集合,分别记录列,正对角线,反对角线是否放置棋。
  2. 递归地尝试每一行,并且横向遍历每一列,检查当前位置是否符合规则,即:
  3. 检查该点所在的列、正对角线、反对角线是否已经放置棋,如果未放置则该点可以放置棋。
  4. 正对角线判断规则,从左上到右下 同一条斜线上的每个位置满足行下标与列下标之差相等
  5. 反对角线判断规则,从右上到左下 同一条斜线上的每个位置满足行下标与列下标之和相等
  6. 当递归的行数达到边界时,退出递归。

代码

from typing import List


class Solution:
    def solveNQueens(self, n):
        self.index = 1
        self.n = n
        # 初始化 n * n的棋盘,默认都为0,未放棋
        self.chessboard = [[0] * self.n for i in range(self.n)]
        # 记录已经放了棋的列
        self.col = set()
        # 记录已经放了棋的正对角线
        self.d1 = set()
        # 记录已经放了棋的反对角线
        self.d2 = set()

        self.result = []

        self.dfs(0)

    def dfs(self, row):
        # 检查每一行能否放棋
        if row >= self.n:
            # 当行数到达边界时,打印结果
            print(self.index, '----------------------')
            self.printq()
            self.index += 1
            self.result.append(self.chessboard)
            return self.result

        # 扫描每一列元素
        for col in range(self.n):
            # d1 表示 从右上到左下 同一条斜线上的每个位置满足行下标与列下标之和相等
            # d2 表示 从左上到右下 同一条斜线上的每个位置满足行下标与列下标之差相等
            d1, d2 = col + row, col - row

            # 检查列是否被占用
            if col in self.col:
                continue

            # 检查正对角线是否被占用 列-行
            if d1 in self.d1:
                continue

            # 检查反对角线是否被占用 列+行
            if d2 in self.d2:
                continue

            # 放置皇后
            self.chessboard[row][col] = 1

            # 标记
            self.col.add(col)
            self.d1.add(d1)
            self.d2.add(d2)

            # 纵向遍历,检查下一行
            self.dfs(row + 1)

            # 回溯
            self.col.remove(col)
            self.d1.remove(d1)
            self.d2.remove(d2)
            self.chessboard[row][col] = 0

    def printq(self):
        for i in self.chessboard:
            x = []
            for j in i:
                if j == 1:
                    x.append('Q ')
                else:
                    x.append('* ')

            print(''.join(x))


def prt(data):
    for line in data:
        print(line)

# 第二种解法
def NQ(data, row, n):
    if row == n:
        prt(data)
        return

    # 检查row当前行中所有列
    for i in range(n):
        # 检查当前节点是否可以放棋
        if check_point(data, row, i):
            data[row][i] = 1
            # 进下一行,中所有的列
            NQ(data, row + 1, n)
            
            data[row][i] = 0


def check_point(data, row, col):
    # 检查 (row, col) 点的位置是否可以放

    n = len(data[0])
    # 检查当前点所在的列中,是否已经放了棋
    for i in range(row):
        if data[i][col] == 1:
            return False

    # 当前行
    for i in range(row):
        # 所有列
        for j in range(n):
            # 检查两个对角线中是否已经放了棋
            if i + j == row + col and data[i][j] == 1:
                return False
            if i - j == row - col and data[i][j] == 1:
                return False
    return True


def main(n):
    data = [[0] * n for _ in range(n)]
    NQ(data, 0, n)


if __name__ == '__main__':
    s = Solution()
    res = s.solveNQueens(4)
    # print(res)
    main(4)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1259242.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FLASK博客系列9——你想成为我的新用户吗?

距离上次发文好久好久了。 先说声抱歉&#xff0c;拖更的毛病我会改掉的。 上次我们教大家如何用后台去管理用户和新增文章&#xff0c;但始终都是单机操作&#xff0c;怎么让你的朋友也来加入你的小站呢&#xff1f;今天我们来为我们的网站增添一个新功能&#xff0c;实现用户…

js 获取数组的最大值与最小值

let arr [1, 2, 5, 8, 10, 100, -1] 1. 使用Math的静态方法max/min Math.max()函数返回给定的一组数中的最大值。 它的语法&#xff1a;Math.max(value1[, value2, ...]) 使用此方法&#xff0c;需要注意&#xff0c;如果没有参数的话&#xff0c;则返回-Infinity。如果有任一…

海外服务器的韧性有多重要?带你了解亚马逊云科技的前世今生

在“第四次工业革命”的浪潮中&#xff0c;云计算已经成为众多互联网企业发展业务灵活性和创新性的核心引擎。然而&#xff0c;随之而来的是各个行业对云服务器&#xff0c;尤其是海外服务器的韧性和可靠性的需求不断提升。在这个充满挑战和竞争的行业环境下&#xff0c;亚马逊…

Vatee万腾的数字创新征途:vatee科技力量的独特奇点

在数字化的时代浪潮中&#xff0c;Vatee万腾如一颗耀眼的明星&#xff0c;以其独特的科技奇点引领着数字创新的征途。无论是在人工智能、大数据、云计算&#xff0c;还是智能化领域&#xff0c;Vatee万腾都展现出了与众不同的创新力量&#xff0c;为科技征途描绘了独一无二的奇…

linux下的工具---gdb

一、gdb简介 GDB,是The GNU Project Debugger 的缩写&#xff0c;是 Linux 下功能全面的调试工具。 GDB支持断点、单步执行、打印变量、观察变量、查看寄存器、查看堆栈等调试手段。 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&am…

神经网络的分类

神经网络可以分为三种主要类型&#xff1a;前馈神经网络、反馈神经网络 和 图神经网络。 一、前馈神经⽹络 前馈神经⽹络&#xff08;feedforward neural network&#xff09;是⼀种简单的神经⽹络&#xff0c;也被称为多层感知机&#xff08;multi-layer perceptron&#xff…

亚马逊云科技实现了奇瑞捷豹路虎SAP系统的上云目标并保持成本优化

11月23日&#xff0c;“2023第八届IDC中国数字化转型年度盛典”正式开启并揭晓“2023 IDC中国未来企业大奖-卓越奖”获奖企业&#xff0c;奇瑞捷豹路虎汽车有限公司&#xff08;以下简称“奇瑞捷豹路虎”&#xff09;凭借“基于云原生的智慧化运营平台”项目&#xff0c;继获得…

2024年最安全的10个Linux桌面发行版

选择合适的 Linux 发行版很重要。 Linux 发行版是一切计算的基石&#xff0c;也是诸君管理硬件组件及交互的重要工具。如果没有强大的安全措施&#xff0c;你的系统很容易受到攻击。值得庆幸的是&#xff0c;Linux 生态系统提供了一系列选项&#xff0c;允许用户根据自己的特定…

Single Patterns : 就一个单例模式调得我蛋疼,1. 单例类的继承树即扩展 2. 系统中单例类的注册及查询,属实有意思!

Intent Ensure a class only has one instance, and provide a global point of access to it. // DesignPatterns.cpp: 定义应用程序的入口点。 //#include "DesignPatterns.h"#include <list> #include <utility> using namespace std;class Single…

计算机视觉面试题-03

1、简单介绍一下sigmoid&#xff0c;relu&#xff0c;softplus&#xff0c;tanh&#xff0c;RBF及其应用场景 这里简单介绍几个激活函数及其应用场景&#xff1a; Sigmoid 函数&#xff08;Logistic 函数&#xff09;&#xff1a; 公式&#xff1a; s i g m a ( x ) 1 1 e …

2.7V 到 5.5V、 12Bit 单通道数模转换器MS5221/5221M

产品简述 MS5221/5221M 是一款 12bit 单通道输出的电压型 DAC &#xff0c;接口 采用三线串口模式&#xff0c;可以兼容 TMS320 、 SPI 、 QSPI 和 Microwire 串 口。 MS5221/5221M 数据有 16bit &#xff0c;包括控制字节&#xff0c;和 12bitDAC 数 据。 MS5221/5221M 电…

CloudCompare 二次开发1

一、在源码中添加插件文件 修改cmakelist 二、插件文件内容 MyPlugin 1、修改程序名称 2、 修改cMakeList 3、 修改cpp和.h 4、修改qc 5、修改json 三、重新编译 cmake 插件 如果不打√那个生成的程序里面没有这个插件显示 generate 然后生成 结果 四、结果显示 dll …

SAS Planet软件介绍与使用教程

软件情况 SAS Planet是一位俄罗斯爱好者创建的的开源应用&#xff0c;该应用可以浏览与下载主流网络地图&#xff0c;包括Google地图、Google地球、Bing地图、Esri 地图、Yandex地图等。 该软件是基于Pascal开发的应用&#xff0c;目前已在github上开源&#xff0c;并使用了GP…

统计学之假设检验

- 原假设和备择假设&#xff1a; - 第一类错误&#xff08;α错误&#xff09;&#xff1a;H0以真为假 *重点关注 第二类错误&#xff08;β错误&#xff09;&#xff1a;H0以假为真 - 假设检验流程&#xff1a; 提出H0和H1&#xff1b;计算检验统计量Z&#xff1…

运维01:云计算

云计算的类型 分类&#xff1a;公有云、私有云、混合云 云计算的服务模式 服务模式分3种&#xff1a; ①IaaS&#xff08;Infrastructure as a Service&#xff09;&#xff1a;基础设施即服务 ②PaaS&#xff08;Platform as a Service&#xff09;&#xff1a;平台即服务…

数据结构——利用堆进行对数组的排序

今天文章的内容是关于我们如何利用堆的特性对我们的数组进行排序&#xff0c;还有就是我们的TopK的问题&#xff0c;这次我们放在的是文件种&#xff0c;我们放入一亿个数字&#xff0c;然后我们取出一亿个数字中最大的十个数&#xff0c;利用上章堆的问题进行解决。 首先就是我…

函数指针数组指针数组传参的本质字符指针

&#x1f680; 作者&#xff1a;阿辉不一般 &#x1f680; 你说呢&#xff1a;不服输的你&#xff0c;他们拿什么赢 &#x1f680; 专栏&#xff1a;爱上C语言 &#x1f680;作图工具&#xff1a;draw.io(免费开源的作图网站) 如果觉得文章对你有帮助的话&#xff0c;还请点赞…

​ 云计算的尽头是轻量应用服务器?带你了解亚马逊Lightsail的卓越优势

很多小伙伴可能都在好奇&#xff0c;轻量应用服务器有什么特点&#xff1f;为什么相较于普通的云服务器&#xff0c;很多用户现在都更青睐于轻量应用服务器?这个“轻”就是它独特的优势所在。轻量应用服务器以其“开箱即用、应用优质、轻松上手、投入划算、运维便捷和稳定可靠…

最近得了一场病 差点要了我的命

最近得了一场病&#xff0c;前后持续了有十多天&#xff0c;时至今日感觉脑袋还是昏昏沉沉的不在状态&#xff0c;感觉像是药吃的&#xff0c;毕竟连着吃了十多天西药&#xff0c;可能人也吃傻了吧&#xff0c;中间还挂了五天水&#xff0c;算是补充了能量。 起因是和老婆去吃…

【Shell】Shell基础学习

一、shell脚本 (1)第一个shell脚本 #!/bin/bash #this is a comment echo "hello world"一个shell脚本永远以“#!”开头,这是一个脚本开始的标记,它是告诉系统执行这个文件需要用某个解释器,后面的/bin/bash就是指明解释器的具体位置。 “#”开头是注释 …