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

难度

困难

题目

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
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)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FPGA模块——AD高速转换模块(并行输出转换的数据)

FPGA模块——AD高速转换模块&#xff08;并行输出转换的数据&#xff09; &#xff08;1&#xff09;AD9280/3PA9280芯片&#xff08;2&#xff09;代码 &#xff08;1&#xff09;AD9280/3PA9280芯片 AD9280/3PA9280芯片的引脚功能&#xff1a; 工作电压2.7到5.5v 数据对应&a…

代码随想录算法训练营第五十七天|739. 每日温度、496.下一个更大元素 I

LeetCode 739. 每日温度 题目链接&#xff1a;739. 每日温度 - 力扣&#xff08;LeetCode&#xff09; 单调栈开始&#xff0c;为什么要用栈&#xff0c;因为栈是先入后出&#xff0c;当我们遍历从前往后的时候&#xff0c;每次遍历的元素都是添加至栈尾&#xff0c;方便我们进…

西南科技大学电路分析基础实验A1(一阶电路的设计)

目录 一、实验目的 二、实验设备 三、预习内容(如:基本原理、电路图、计算值等) 四、实验数据及结果分析(预习写必要实验步骤和表格) 1. 观测一阶电

搜索百度可以直接生成代码拉

先看效果图&#xff1a; 使用示例&#xff1a; 比如我要搜索“JS取一个数在两个数更近”的方法&#xff0c;直接搜“JS取一个数在两个数更近”&#xff0c;点击百度一下&#xff0c;就会出现想要的代码&#xff0c;如上图。

《金融科技行业2023年专利分析白皮书》发布——科技变革金融,专利助力行业发展

金融是国民经济的血脉&#xff0c;是国家核心竞争力的重要组成部分&#xff0c;金融高质量发展成为2023年中央金融工作的重要议题。《中国金融科技调查报告》中指出&#xff0c;我国金融服务业在科技的助力下&#xff0c;从1.0时代的“信息科技金融”、2.0时代的“互联网金融”…

坚鹏:数字金融——金融行业的数字科技和智能化转型培训圆满结束

中国邮政储蓄银行拥有优良的资产质量和显著的成长潜力&#xff0c;是中国领先的大型零售银行。2016年9月在香港联交所挂牌上市&#xff0c;2019年12月在上交所挂牌上市。中国邮政储蓄银行拥有近4万个营业网点&#xff0c;服务个人客户超6.5亿户。2022年&#xff0c;在《银行家》…

力扣hot100 滑动窗口最大值 单调队列

&#x1f468;‍&#x1f3eb; 题目地址 &#x1f37b; AC code class Solution {public int[] maxSlidingWindow(int[] nums, int k){int n nums.length;int[] res new int[n - k 1]; // 单调递减队列int[] q new int[n];// q数组维护的是元素在 nums 数组对应的下标int…

从零构建属于自己的GPT系列1:预处理模块(逐行代码解读)、文本tokenizer化

1 训练数据 在本任务的训练数据中&#xff0c;我选择了金庸的15本小说&#xff0c;全部都是txt文件 数据打开后的样子 数据预处理需要做的事情就是使用huggingface的transformers包的tokenizer模块&#xff0c;将文本转化为token 最后生成的文件就是train_novel.pkl文件&a…

动态网页从数据库取信息,然后展示。

把数据库的驱动放在bin目录下。 通过servlet 读取数据库的内容&#xff0c;生成session,然后跨页面传给展示页。 package src;import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSe…

sprintf函数

1.头文件&#xff1a;#include <stdio.h> 2.函数原型&#xff1a;int sprintf ( char * str, const char * format, ... ) 3.函数功能&#xff1a;将数据格式化为字符串&#xff0c;再写入到字符串中 4.参数分析&#xff1a; str&#xff1a;是字符串指针&#xff0c…

SpringBoot——国际化

优质博文&#xff1a;IT-BLOG-CN 一、Spring 编写国际化时的步骤 【1】编写国际化配置文件&#xff1b; 【2】使用ResourceBundleMessageSource管理国际化资源文件&#xff1b; 【3】在页面使用ftp:message取出国际化内容&#xff1b; 二、SpringBoot编写国际化步骤 【1】创…

JavaScript WebApi(二) 详解

监听事件 介绍 事件监听是一种用于在特定条件下执行代码的编程技术。在Web开发中&#xff0c;事件监听器可以用于捕获和响应用户与页面交互的各种操作&#xff0c;如点击、滚动、输入等。 事件监听的基本原理是&#xff0c;通过在特定元素上注册事件监听器&#xff0c;当事件…

每日一题:LeetCode-202.快乐数(一点都不快乐)

每日一题系列&#xff08;day 06&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

【古诗生成AI实战】之三——任务加载器与预处理器

本章内容属于数据处理阶段&#xff0c;将分别介绍任务加载器task和预处理器processor。 [1] 数据集 在深入探讨数据处理的具体步骤之前&#xff0c;让我们先了解一下我们将要使用的数据集的形式。 本项目采用的是七绝数据集&#xff0c;总计83072条古诗&#xff0c;其形式如下&…

单片机学习10——独立按键

独立按键输入检测&#xff1a; #include<reg52.h>sbit LED1P1^0; sbit KEY1P3^4;void main() {KEY11;while(1){if(KEY10) //KEY1按下{LED10; //LED1被点亮}else{LED11;}} } 按键 #include<reg52.h>#define uchar unsigned char #define uint unsigned intsbit …

Java LeetCode篇-深入了解关于数组的经典解法

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 轮转数组 1.1 使用移位的方式 1.2 使用三次数组逆转法 2.0 消失的数字 2.1 使用相减法 2.2 使用异或的方式 3.0 合并两个有序数组 3.1 使用三指针方式 3.2 使用合…

浅谈UML的概念和模型之UML九种图

1、用例图&#xff08;use case diagrams&#xff09; 【概念】描述用户需求&#xff0c;从用户的角度描述系统的功能 【描述方式】椭圆表示某个用例&#xff1b;人形符号表示角色 【目的】帮组开发团队以一种可视化的方式理解系统的功能需求 【用例图】 2、静态图 类图&…

新形势下,2024年企业数字化转型该如何进行?

2023年已然接近尾声&#xff0c;各大企业都陆续开始了各种工作总结与来年规划。然而在大多传统企业中&#xff0c;负责数字化转型的部门人员则显得略微尴尬。 如何正确认识数字化、如何制定数字化年度目标以及如何快速体现数字化转型的价值&#xff0c;成为了数字化工作难以逾…

PlantUML语法(全)及使用教程-时序图

目录 1. 参与者1.1、参与者说明1.2、背景色1.3、参与者顺序 2. 消息和箭头2.1、 文本对其方式2.2、响应信息显示在箭头下面2.3、箭头设置2.4、修改箭头颜色2.5、对消息排序 3. 页面标题、眉角、页脚4. 分割页面5. 生命线6. 填充区设置7. 注释8. 移除脚注9. 组合信息9.1、alt/el…

传音荣获2023首届全国人工智能应用场景创新挑战赛“智能家居专项赛”三等奖

近日&#xff0c;中国人工智能学会与科技部新一代人工智能发展研究中心联合举办2023首届全国人工智能应用场景创新挑战赛&#xff08;2023 1st China’s Innovation Challenge on Artificial Intelligence Application Scene&#xff0c;以下简称CICAS 2023)&#xff0c;吸引了…