皇后之战:揭秘N皇后问题的多维解法与智慧【python 力扣52题】

2024-04-21 03:36

本文主要是介绍皇后之战:揭秘N皇后问题的多维解法与智慧【python 力扣52题】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。
会一些的技术:数据分析、算法、SQL、大数据相关、python
欢迎加入社区:码上找工作
作者专栏每日更新:
LeetCode解锁1000题: 打怪升级之旅
python数据分析可视化:企业实战案例
备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

题目描述

给定一个整数 n,返回 n×n 棋盘上的 N 皇后问题的不同解决方案的数量。

每一种解法包含一个明确的 n×n 棋盘上的皇后放置方式,其中 'Q' 代表一个皇后,而 '.' 代表空位。每个皇后都必须满足不能与其他皇后在同一行、同一列或同一对角线上。

输入格式
  • n:一个整数,表示棋盘的大小。
输出格式
  • 返回所有独特的 n 皇后问题的解决方案数量。

示例

示例 1

在这里插入图片描述

输入: n = 4
输出: 2
示例 2
输入: n = 1
输出: 1

注意
LeetCode题目51 "N皇后"与题目52 "N皇后II"虽然都是基于经典的N皇后问题,但两者的主要区别在于输出的需求不同:

N皇后 (题目 51)

  • 目标:找出所有可能的N皇后解决方案的具体棋盘布局。
  • 输出:返回所有解决方案,每个解决方案都详细展示了皇后的具体摆放位置。每个解决方案是一个包含n个字符串的列表,每个字符串长度为n,表示棋盘的一行,其中’Q’表示皇后,'.'表示空位。
  • 解法关注点:除了求解算法的有效性外,还需要关注如何构造并展示完整的棋盘布局。

N皇后 II (题目 52)

  • 目标:仅计算N皇后问题的不同解决方案数量。
  • 输出:返回解决方案的数量,而不是具体的棋盘布局。
  • 解法关注点:主要关注于优化算法的效率以快速计算出解决方案的总数,而不需要构造棋盘的具体布局。
    解法对比
    尽管两个问题在解法上可能使用类似的技术(如回溯法),51题需要更多的空间和逻辑来存储和展示所有可能的棋盘配置,而52题则更注重于计数优化,可能会使用更加精简的数据结构(如位运算)来加速计数过程。

方法一:回溯算法

解题步骤
  1. 初始化变量:创建一个用于存储当前行皇后位置的列表。
  2. 定义回溯函数:递归定义函数以尝试每一行的每个位置。
  3. 合法性检查:检查当前位置放置皇后是否合法,即检查列和两个方向的对角线。
  4. 递归与计数:递归地放置下一个皇后,如果完成一种有效布局则增加计数。
完整的规范代码
def totalNQueens(n):"""计算 n 皇后问题的解决方案总数:param n: int, 棋盘大小:return: int, 解决方案总数"""def backtrack(row, diagonals, anti_diagonals, cols):if row == n:nonlocal countcount += 1returnfor col in range(n):curr_diagonal = row - colcurr_anti_diagonal = row + colif (col in cols or curr_diagonal in diagonals or curr_anti_diagonal in anti_diagonals):continuecols.add(col)diagonals.add(curr_diagonal)anti_diagonals.add(curr_anti_diagonal)backtrack(row + 1, diagonals, anti_diagonals, cols)cols.remove(col)diagonals.remove(curr_diagonal)anti_diagonals.remove(curr_anti_diagonal)count = 0backtrack(0, set(), set(), set())return count# 示例调用
print(totalNQueens(4))  # 输出: 2
算法分析
  • 时间复杂度:(O(n!)),尽管有剪枝,每层递归的选择数接近 n
  • 空间复杂度:(O(n)),递归栈深度加用于存储状态的空间。

方法二:位运算优化的回溯算法

解题步骤
  1. 位运算优化:使用位运算代替集合操作,提高效率。
  2. 定义位运算回溯函数:使用位掩码表示列和对角线的占用状态,通过位运算快速检查和修改状态。
  3. 递归与计数:递归放置皇后,完成布局时增加解决方案计数。
完整的规范代码
def totalNQueens(n):"""计算 n 皇后问题的解决方案总数,使用位运算进行优化:param n: int, 棋盘大小:return: int, 解决方案总数"""def solve(row, hills, next_row, dales):if row == n:nonlocal countcount += 1returnfree_columns = columns & ~(hills | next_row | dales)while free_columns:curr_column = -free_columns & free_columnssolve(row + 1, (hills | curr_column) << 1, next_row | curr_column, (dales | curr_column) >> 1)free_columns &= free_columns - 1columns = (1 << n) - 1count = 0solve(0, 0, 0, 0)return count# 示例调用
print(totalNQueens(4))  # 输出: 2
算法分析
  • 时间复杂度:(O(n!)),位运算显著提高了效率,但最坏情况下仍需尝试所有可能。
  • 空间复杂度:(O(n)),递归深度决定了空间复杂度,虽然使用位运算减少了空间占用。

方法三:迭代回溯

解题步骤
  1. 使用栈模拟递归:使用栈来模拟递归过程,避免函数调用的开销。
  2. 迭代处理:在迭代中管理棋盘状态和递归变量,以模拟递归调用栈的行为。
完整的规范代码
def totalNQueens(n):"""使用迭代回溯解决 n 皇后问题:param n: int, 棋盘大小:return: int, 解决方案总数"""stack = [(0, 0, 0, 0)]  # (row, hills, next_row, dales)count = 0while stack:row, hills, next_row, dales = stack.pop()if row == n:count += 1continuefree_columns = ((1 << n) - 1) & ~(hills | next_row | dales)while free_columns:curr_column = -free_columns & free_columnsstack.append((row + 1, (hills | curr_column) << 1, next_row | curr_column, (dales | curr_column) >> 1))free_columns &= free_columns - 1return count# 示例调用
print(totalNQueens(4))  # 输出: 2
算法分析
  • 时间复杂度:(O(n!)),迭代的方式减少了递归调用开销,但仍然需要尝试所有可能的放置方式。
  • 空间复杂度:(O(n)),虽然使用栈来模拟递归,但空间复杂度与递归方法相当。

不同算法的优劣势对比

特征方法一: 回溯算法方法二: 位运算优化回溯方法三: 迭代回溯
时间复杂度(O(n!))(O(n!))(O(n!))
空间复杂度(O(n))(O(n))(O(n))
优势- 易于理解和实现- 空间效率高- 避免递归调用开销
劣势- 空间消耗较大- 理解和实现较为复杂- 状态维护较为复杂

应用示例

科学研究
N皇后问题常用于算法研究和教学,特别是在探讨组合数学、算法优化、复杂度分析等领域。此问题的不同解决策略可用于教授递归、回溯及其优化。

算法竞赛
在算法竞赛中,N皇后问题是经典问题,经常出现在各类比

赛和面试中,作为测试程序员解决复杂问题能力的一种方式。

通过以上方法和示例,可以深入理解和掌握N皇后问题的多种解决方案及其应用场景。这些技术不仅限于此问题,还可广泛应用于其他需要递归和回溯解决的问题中。

这篇关于皇后之战:揭秘N皇后问题的多维解法与智慧【python 力扣52题】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/922067

相关文章

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Python Websockets库的使用指南

《PythonWebsockets库的使用指南》pythonwebsockets库是一个用于创建WebSocket服务器和客户端的Python库,它提供了一种简单的方式来实现实时通信,支持异步和同步... 目录一、WebSocket 简介二、python 的 websockets 库安装三、完整代码示例1.

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Python使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

Python+PyQt5实现多屏幕协同播放功能

《Python+PyQt5实现多屏幕协同播放功能》在现代会议展示、数字广告、展览展示等场景中,多屏幕协同播放已成为刚需,下面我们就来看看如何利用Python和PyQt5开发一套功能强大的跨屏播控系统吧... 目录一、项目概述:突破传统播放限制二、核心技术解析2.1 多屏管理机制2.2 播放引擎设计2.3 专

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2