Python算法题集_N 皇后

news2025/4/5 3:13:00

Python算法题集_N 皇后

  • 题51:N 皇后
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【规则遍历合理性+回溯】
    • 2) 改进版一【线状态检测合理性+回溯】
    • 3) 改进版二【单行矩阵+回溯】
  • 4. 最优算法
  • 5. 相关资源

本文为Python算法题集之一的代码示例

题51:N 皇后

1. 示例说明

  • 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

    n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

    给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

    每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q''.' 分别代表了皇后和空位。

    示例 1:

    img

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

    示例 2:

    输入:n = 1
    输出:[["Q"]]
    

    提示:

    • 1 <= n <= 9

2. 题目解析

- 题意分解

  1. 本题是在矩阵内摆放Q皇后,并且不违反规则的问题
  2. 矩阵大小为nn,要放n个Q皇后,代表每行、每列最多有一个Q皇后;额外的规则是斜线,左斜线有(2n-1)条,右斜线有(2*n-1)条【类似2.5d地图】
  3. 核心计算有两层,一是回溯遍历,二是当前位置Q是否合乎规则判断
  4. 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。

- 优化思路

  1. 通常优化:减少循环层次

  2. 通常优化:增加分支,减少计算集

  3. 通常优化:采用内置算法来提升计算速度

  4. 分析题目特点,分析最优解

    1. 可以进行规则遍历进行合理性函数检测

    2. 可以保存列、左斜线、右斜线是否被占据的状态,通过线状态检测判定是否合理

    3. 因每行仅有一个Q皇后,因此整个矩阵可以用一维列表保存,位置代表行,值代表此行的Q皇后列下标

- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大【可把页面视为功能测试】,因此需要本地化测试解决数据波动问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 本题本地化超时测试用例自己生成,详见章节【最优算法】,代码文件包含在【相关资源】中

3. 代码展开

1) 标准求解【规则遍历合理性+回溯】

通过规则遍历的合理性函数,实现回溯求解

页面功能测试,凄凄惨惨,超过28%

import CheckFuncPerf as cfp

class Solution:
 def solveNQueens_base(self, n):
     def isValid(board, row, col):
         ilen = len(board)
         for irow in range(row):
             if board[irow][col] == 'Q':
                 return False
         for irow, icol in zip(range(row - 1, -1, -1), range(col + 1, ilen, 1)):
             if board[irow][icol] == 'Q':
                 return False
         for irow, icol in zip(range(row - 1, -1, -1), range(col - 1, -1, -1)):
             if board[irow][icol] == 'Q':
                 return False
         return True
     board = [['.'] * n for x in range(n)]
     result, isize = [], n
     def backtrack(irow):
         if irow == isize:
             tmpmap = [''.join(x) for x in board]
             result.append(tmpmap)
             return
         for icol in range(isize):
             if not isValid(board, irow, icol):
                 continue
             board[irow][icol] = 'Q'
             backtrack(irow + 1)
             board[irow][icol] = '.'
     backtrack(0)
     return result

aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.solveNQueens_base, ilen)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))
 
# 运行结果
函数 solveNQueens_base 的运行时间为 61887.03 ms;内存使用量为 75908.00 KB 执行结果 = 73712

2) 改进版一【线状态检测合理性+回溯】

通过线状态检测位置合理性,实现回溯求解,此检测方法实际上将二维平面的遍历转化为了一维的循环,减少了一层循环

页面功能测试,性能一般,超过76%

import CheckFuncPerf as cfp

class Solution:
 def solveNQueens_ext1(self, n):
     from copy import deepcopy
     def backtrack(irow, cols, dgs, adgs, currmap, result):
         ilen = len(cols)
         if irow == ilen:
             result.append(deepcopy(currmap))
             return result
         for icol in range(ilen):
             if cols[icol] or dgs[irow + icol] or adgs[irow - icol + ilen - 1]:
                 continue
             currmap[irow][icol] = "Q"
             cols[icol] = True
             dgs[irow + icol] = True
             adgs[irow - icol + ilen - 1] = True
             backtrack(irow + 1, cols, dgs, adgs, currmap, result)
             adgs[irow - icol + ilen - 1] = False
             dgs[irow + icol] = False
             cols[icol] = False
             currmap[irow][icol] = "."
     statecols = [False for x in range(n)]
     statedgs = [False for x in range(2 * n - 1)]
     stateadgs = [False for x in range(2 * n - 1)]
     currmap = [["." for x in range(n)] for y in range(n)]
     result = []
     backtrack(0, statecols, statedgs, stateadgs, currmap, result)
     for statemap in result:
         for irow in range(len(statemap)):
             statemap[irow] = "".join(statemap[irow])
     return result

aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.solveNQueens_ext1, ilen)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))
 
# 运行结果
函数 solveNQueens_ext1 的运行时间为 13925.13 ms;内存使用量为 199784.00 KB 执行结果 = 73712

3) 改进版二【单行矩阵+回溯】

使用单行列表存储矩阵,通过计算判断合理性,实现回溯算法

页面功能测试,马马虎虎,超过53%

import CheckFuncPerf as cfp

class Solution:
 def solveNQueens_ext2(self, n):
     result = []
     def nqbacktrack(currmap):
         if len(currmap) == n:
             result.append(["." * (x-1) +"Q" +"." * (n-x) for x in currmap])
         rows = [x for x in range(1, n+1)]
         for irow in rows:
             if irow in currmap:
                 continue
             tmpFlag = False
             for icol, val in enumerate(currmap):
                 if abs(val-irow) == len(currmap)-icol:
                     tmpFlag = True
             if tmpFlag:
                 continue
             currmap.append(irow)
             nqbacktrack(currmap)
             currmap.pop()
     nqbacktrack([])
     return result

aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.solveNQueens_ext2, ilen)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))
 
# 运行结果
函数 solveNQueens_ext2 的运行时间为 31577.39 ms;内存使用量为 66228.00 KB 执行结果 = 73712

4. 最优算法

根据本地日志分析,最优算法为第2种方式【线状态检测合理性+回溯】solveNQueens_ext1

本题测试数据,似乎能推出以下结论:

  1. 布尔计算性能优于数值计算
  2. 减少循环层次可以明显提升性能
ilen = 13
aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.solveNQueens_base, ilen)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))
result = cfp.getTimeMemoryStr(aSolution.solveNQueens_ext1, ilen)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))
result = cfp.getTimeMemoryStr(aSolution.solveNQueens_ext2, ilen)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))

# 算法本地速度实测比较
函数 solveNQueens_base 的运行时间为 61887.03 ms;内存使用量为 75908.00 KB 执行结果 = 73712
函数 solveNQueens_ext1 的运行时间为 13925.13 ms;内存使用量为 199784.00 KB 执行结果 = 73712
函数 solveNQueens_ext2 的运行时间为 31577.39 ms;内存使用量为 66228.00 KB 执行结果 = 73712

5. 相关资源

本文代码已上传到CSDN,地址:Python算法题源代码_LeetCode(力扣)_N皇后

一日练,一日功,一日不练十日空

may the odds be ever in your favor ~

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

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

相关文章

威步安全技术保护铁路免受网络威胁

IoW的TrainCAS列车碰撞预警系统保护铁路列车免受网络攻击。TrainCAS系统内置的高端技术及其被非法利用的风险&#xff0c;让安全和知识产权保护成为公司的首要任务。TrainCAS软件及其轨道图通过CodeMeter AxProtector和Core API工具的结合得到保护&#xff0c;有效防止未授权使…

任务调度新境界:探秘ScheduledExecutorService的异步魔力

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 任务调度新境界&#xff1a;探秘ScheduledExecutorService的异步魔力 前言ScheduledExecutorService的基本概念基本概念&#xff1a;为何它是 Java 中任务调度的首选工具&#xff1a;基本用法&#xf…

Milvus 向量数据库实践 - 1

假定你已经安装了docker、docker-compose 环境 参考的文档如下&#xff1a; Milvus技术探究 - 知乎 MilvusClient() - Pymilvus v2.3.x for Milvus 一文带你入门向量数据库milvus 一、在docker上安装单机模式milvus数据库 1、 进入milvus官网&#xff1a; Install Milvus Stand…

【C++】string类的基础操作

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读 1. 基本概述 2. string类对象的常见构造 3. string类对象的容量操作 4. string类对象的访问及遍历操作 5. 迭代器 6.…

noetic ros配置因时机械夹爪的驱动

noetic ros配置因时机械夹爪的驱动文件 配置编译教程解决方案 配置编译教程 1.inspire_robot 包支持因时机器人公司的机械夹爪在ROS平台上的使用&#xff0c;我们在ros noetic环境下进行了测试。 2.为了使程序能够正常运行&#xff0c;需要执行以下环境配置操作&#xff1a;&a…

从一个问题开始聊聊clickhouse的物化视图

【问题】 今天有A问我一个问题&#xff0c;我明明创建了一个物化视图&#xff0c;源表是有数据的&#xff0c;为什么查询物化视图就没有数据&#xff1f; 创建物化视图的SQL示意如下&#xff1a; CREATE MATERIALIZED VIEW schema1.test_mvon cluster clusterNameTO schema1…

玩转安卓之配置gradle-8.2.1

概述&#xff1a;看了一下&#xff0c;由于gradle是国外的&#xff0c;所以下载速度很慢&#xff0c;这个老师又是很菜的类型&#xff0c;同学又不会&#xff0c;于是曹某就写这一篇文章&#xff0c;教大家学会简单的为安卓配置gradle-8.2.1。 第一步&#xff1a;下载gradle-8…

【问题解决】| 关于vscode调试python文件 报错 且直接运行正常的诡异情况记录

关于python的debug报错&#xff0c;其实很奇怪 首先&#xff0c;对于工作区代码&#xff0c;我们可以通过CtrlShiftP 来切换Python解释器 这样的话&#xff0c;工作区的代码就不会报import error 而且这样的话是可以运行跑通的&#xff0c;但最抽象的一集来了&#xff0c;这…

JavaScript 作用域详解:如何影响变量生命周期

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

总结Redis的原理

一、为什么要使用Redis 缓解数据库访问压力mysql读请求进行磁盘I/O速度慢&#xff0c;给数据库加Redis缓存&#xff08;参考CPU缓存&#xff09;&#xff0c;将数据缓存在内存中&#xff0c;省略了I/O操作 二、Redis数据管理 2.1 redis数据的删除 定时删除惰性删除内存淘汰…

多层菜单的实现方案(含HierarchicalDataTemplate使用)

1、递归 下面是Winform的递归添加菜单栏数据&#xff0c;数据设置好父子id方便递归使用 在TreeView的控件窗口加载时&#xff0c;调用递归加载菜单 private void LoadTvMenu(){this.nodeList objService.GetAllMenu(); // 通过Service得到全部数据// 创建一个根节点this.t…

NCDA设计大赛中设定画命题解读

一年一度的未来设计师全国高校数字艺术设计大赛&#xff08;NCDA&#xff09;正在如火如荼的进行中&#xff0c;各高校的大学生和指导老师们也都在着手准备中。今天我们就特地来说说它的数字绘画命题之一的设定画选项&#xff0c;为了使大家更好地参加本次比赛&#xff0c;本文…

博客系统测试

文章目录 1.项目背景介绍2.功能介绍3.手动测试3.1编写测试用例3.2项目测试3.2.1登录测试3.2.2查看详情页面3.2.3编辑页面3.2.4删除博客3.2.5注销用户 大家好&#xff0c;我是晓星航。今天为大家带来的是 博客系统测试 相关的讲解&#xff01;&#x1f600; 1.项目背景介绍 项…

Vue.js+SpringBoot开发农村物流配送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2.1 快递信息管理&#xff1a;2.2.2 位置信息管理&#xff1a;2.2.3 配送人员分配&#xff1a;2.2.4 路线规划&#xff1a;2.2.5 个人中心&#xff1a;2.2.6 退换快递处理&#xff1a;…

DxO ViewPoint:摄影师的最 佳拍档,记录世界的每一刻精彩 mac/win版

DxO ViewPoint是一款革命性的摄影软件&#xff0c;它以其独特的功能和卓越的性能&#xff0c;重新定义了摄影体验。这款软件不仅提供了丰富的摄影工具&#xff0c;还通过先进的算法和技术&#xff0c;让摄影师能够轻松捕捉、管理和展示他们的作品。 DxO ViewPoint 软件获取 Dx…

《幸运的基督徒》Python

题目描述 有15个基督徒和15个非基督徒在海上遇险&#xff0c; 为了能让一部分人活下来不得不将其中15个人扔到海里面去&#xff0c; 有个人想了个办法就是大家围成一个圈&#xff0c;由某个人开始从1报数&#xff0c; 报到9的人就扔到海里面&#xff0c;他后面的人接着从1开始报…

unity学习(49)——服务器三次注册限制以及数据库化角色信息4--角色信息数据库化

1.此处下断开始调试,list函数内就有问题&#xff1a; 2. 现在的问题是只读不写&#xff01;32行就是写入部分的代码&#xff1a; 3. 很奇怪&#xff0c;调试的时候确实是写进来了 程序正常执行后&#xff0c;文件中数据也没有消失 关闭服务器文件内容依旧正常。 players包含所…

px2rem实现vue项目响应式布局

第一步 首先需要在项目中安装px2rem插件 npm install postcss-px2rem px2rem-loader --save 第二步 在项目src目录下新建util文件夹&#xff0c;在util文件夹下新建rem.js文件&#xff0c;内容如下&#xff1a; // rem等比适配配置文件 // 基准大小 const baseSize 14 //…

day14_异常

今日内容 零、 复习昨日 一、日期类 二、异常 零、 复习昨日 1为什么要重写toString Object类toString返回的是对象名字地址,无意义子类重写toString() 返回的对象属性内容 2为什么要重写equals Object类equals判断是对象的地址值是否相等,无意义子类重写equals,为了判断对象的…

电商分享沙龙干货:做印尼电商如何提高顾客购买意愿?

“得印尼者得东南亚” 这是诸多在印尼掘金的电商人的共识。2.7亿人口、GDP年增速稳定在5%、平均年龄在30岁上下、较强的消费能力……这些都使得印尼成为电商人掘金东南亚的首选之地。 图源&#xff1a;freepik 但近几年来&#xff0c;印尼政府不断调整关税&#xff0c;限制电商…