每天一道算法题: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 Listclass Solution:def solveNQueens(self, n):self.index = 1self.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 += 1self.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] = 0def 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] = 0def 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 Falseif i - j == row - col and data[i][j] == 1:return Falsereturn Truedef 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.hqwc.cn/news/223434.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于水杯水

主要难点1.碰撞 &#xff08;水杯移动太快碰撞出问题 2.吃水 &#xff08;参数碰撞问题水随着时间变少 一.首先发射源&#xff1a;不易过小或者过大 过小>>>>水解算空间大水动态剧烈稳定慢 过大>>>>穿插漏水&#xff08;不用担心一般model环节会给&am…

Ubuntu安装Vmtools (最新安装教程)

Ubuntu安装Vmtools 1. 设置root用户密码2. 切换root用户3. 安装vmools 1. 设置root用户密码 出现认证失败&#xff08;Authentication failure&#xff09;的原因有两种&#xff0c;要么是密码输入错误&#xff0c;要么是新安装的系统还没有给root设置密码&#xff0c;&#x…

Python---可变和非可变数据类型

在Python中一共有7种数据类型&#xff1a; 数值&#xff08;int整型、float浮点类型&#xff09;、bool类型&#xff08;True和False&#xff09;、字符串类型&#xff08;str&#xff09;、元组&#xff08;tuple 1,2,3&#xff09;、列表&#xff08;list [1, 2, 3]&#xf…

i社为什么不出游戏了?

I社&#xff0c;即国际知名的游戏公司&#xff0c;近来为何鲜有新游问世&#xff1f;曾经风靡一时的游戏开发者&#xff0c;如今为何陷入了沉寂&#xff1f;这其中的种种原因&#xff0c;值得我们深入剖析。 首先&#xff0c;I社近期的沉寂可能与其内部管理层的调整和战略规划…

MATLAB中FFT频谱分析使用详解

文章目录 语法说明语法一&#xff1a;Y fft(X)fft(X)返回X长度的傅里叶变换 语法二&#xff1a;Y fft(X,N)如果 X的长度小于 N&#xff0c;则为 X补上尾零以达到长度 N(FFT插值)双边谱转换为单边谱 如果 X 的长度大于 N&#xff0c;则对 X 进行截断以达到长度 N。 语法三&…

CSS3制作3D爱心动画

1、什么是CSS css&#xff0c;即层叠样式表的简称&#xff0c;是一种标记语言&#xff0c;有浏览器解释执行用来使页面变得更美观。 2、选择器 css3中新增了一些选择器&#xff0c;如下&#xff1a; 3、新样式 边框 css3新增了三个边框属性&#xff0c;分别是&#xff1a; bo…

Flutter | TextField长按时选项菜单复制、粘贴显示为英文问题解决

Flutter | TextField长按时选项菜单复制、粘贴显示为英文问题解决 问题描述&#xff1a; 长按TextField后&#xff0c;显示剪切、复制等选项为英文&#xff0c;如下图所示&#xff0c;这是因为问未设置语言本地化&#xff0c;我们需要进行设置。 首先在pubspec.yaml加入以下依赖…

【力扣】907.子数组的最小值之和

【力扣】907.子数组的最小值之和 文章目录 【力扣】907.子数组的最小值之和1. 题目介绍2. 解法2.1 方法一&#xff1a;单调栈2.2 方法二&#xff1a;动态规划 3. Danger参考 1. 题目介绍 给定一个整数数组 arr&#xff0c;找到 min(b) 的总和&#xff0c;其中 b 的范围为 arr …

linux task_struct中进程调度相关的变量记录

参考文章&#xff1a; Linux进程调度分析记录&#xff0c;进程优先级&#xff0c;隔离处理器&#xff0c;isolcpus - 知乎

Python break用法详解

Python 语言没有提供 goto 语句来控制程序的跳转&#xff0c;这种做法虽然提高了程序流程控制的可读性&#xff0c;但降低了灵活性。为了弥补这种不足&#xff0c;Python 提供了 continue 和 break 来控制循环结构。本节先讲解 break 的用法。 某些时候&#xff0c;需要在某种…

JavaScript解构对象

之前介绍了数组解构&#xff0c;本文来介绍一下对象如何解构&#xff1b; 前言 现在我们有这样的一个数组&#xff1a; const restaurant {name: Classico Italiano,location: Via Angelo Tavanti 23, Firenze, Italy,categories: [Italian, Pizzeria, Vegetarian, Organic…

【python】--文件/文件夹读写及操作

目录 一、文件读写1、文件读写代码示例 二、文件/文件夹操作1、代码示例 一、文件读写 读写文件就是请求操作系统打开一个文件对象&#xff08;通常称为文件描述符&#xff09;&#xff0c;然后通过操作系统提供的接口从这个文件对象中读取数据&#xff08;读文件&#xff09;…