LeetCode【0052】N皇后II

news2024/12/28 3:36:47

本文目录

  • 1 中文题目
  • 2 求解方法:位运算+回溯法
    • 2.1 方法思路
    • 2.2 Python代码
    • 2.3 复杂度分析
  • 3 题目总结

1 中文题目

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

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

示例:

在这里插入图片描述

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

提示:

  • 1 ≤ n ≤ 9 1 \leq n \leq 9 1n9

2 求解方法:位运算+回溯法

2.1 方法思路

方法核心

使用位运算优化的回溯算法,通过三个整数的二进制位来分别记录已占用的列和两个方向的对角线,利用位运算快速计算可用位置并更新状态,避免了使用集合带来的开销,同时通过位运算的特性快速获取和更新可用位置。

实现步骤

(1)状态表示:

  • 使用整数的二进制位表示棋盘状态,每个二进制位1表示该位置被占用
  • columns记录列的占用情况,diagonals1记录主对角线占用情况,diagonals2记录副对角线占用情况

(2)可用位置计算:

  • 使用位运算计算当前行可用位置
  • 通过OR运算合并所有限制
  • 通过NOT运算取反获得可用位置
  • 通过AND运算限制在棋盘范围内

(3)位置选择和更新:

  • 使用位运算获取最右边的可用位置
  • 更新三个状态值
  • 递归处理下一行
  • 统计所有可能的解数量

(4)回溯过程:

  • 对每一行遍历所有可用位置
  • 递归处理下一行
  • 累加所有可能的解数量
  • 当处理完最后一行时返回1

方法示例

以 n = 4 为例:

初始状态:
row = 0
columns = 0000
diagonals1 = 0000
diagonals2 = 0000

第一步(第一行):
available_positions = 1111
选择position = 0001(最右位置)
递归到下一行:
columns = 0001
diagonals1 = 0010
diagonals2 = 0000

第二步(第二行):
available_positions = 1100
选择position = 0100
递归到下一行:
columns = 0101
diagonals1 = 1010
diagonals2 = 0010

第三步(第三行):
available_positions = 1000
选择position = 1000
递归到下一行:
columns = 1101
diagonals1 = 0100
diagonals2 = 0101

第四步(第四行):
available_positions = 0010
选择position = 0010
找到一个解:
.Q..
...Q
Q...
..Q.

继续回溯找其他解...

2.2 Python代码

class Solution:
    def totalNQueens(self, n: int) -> int:
        # 使用整数来记录已占用的列和对角线
        # columns记录已占用的列
        # diagonals1记录已占用的主对角线(从左上到右下)
        # diagonals2记录已占用的副对角线(从右上到左下)
        def backtrack(row: int, columns: int, diagonals1: int, diagonals2: int) -> int:
            # 当遍历完所有行,找到一个有效解
            if row == n:
                return 1
            
            # 记录当前行所有可能解的数量
            count = 0
            
            # 当前行可用位置的二进制表示
            # (~(columns | diagonals1 | diagonals2)) & ((1 << n) - 1) 
            # 计算当前行所有可放置皇后的位置
            available_positions = ((1 << n) - 1) & \
                                (~(columns | diagonals1 | diagonals2))
            
            # 遍历所有可用位置
            while available_positions:
                # 获取最低位的1(即最右边可用的位置)
                position = available_positions & (-available_positions)
                # 将当前位置从可用位置中移除
                available_positions = available_positions & (available_positions - 1)
                
                # 递归到下一行,更新三个限制条件
                # columns | position:在columns中标记当前列已使用
                # (diagonals1 | position) << 1:主对角线限制在下一行的位置
                # (diagonals2 | position) >> 1:副对角线限制在下一行的位置
                count += backtrack(row + 1,
                                 columns | position,
                                 (diagonals1 | position) << 1,
                                 (diagonals2 | position) >> 1)
            
            return count
            
        return backtrack(0, 0, 0, 0)

2.3 复杂度分析

  • 时间复杂度:O(N!)
    • 第一行有N种选择
    • 第二行最多有N-1种选择
    • 第三行最多有N-2种选择
    • 依此类推
    • 总的时间复杂度约为O(N!)
    • 位运算优化使得实际运行时间远小于理论值
  • 空间复杂度:O(N)
    • 递归调用栈深度为N:O(N)
    • 使用三个整数存储状态:O(1)

3 题目总结

题目难度:困难
数据结构:数组
应用算法:位运算、回溯法

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

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

相关文章

C语言-详细讲解-P1009 [NOIP1998 普及组] 高精度阶乘之和

目录 1.题目要求 2.题目解读 3.代码实现 4.一些小细节 1.数组储存大整数方式 2.memset函数介绍 3.digit与sum的关系 1.题目要求 2.题目解读 这道题本质就是高精度乘法高精度加法的结合&#xff0c;我之前有出过 高精度算法-保姆级讲解 希望详细了解的小伙伴可以去…

浅谈:基于三维场景的视频融合方法

视频融合技术的出现可以追溯到 1996 年 , Paul Debevec等 提出了与视点相关的纹理混合方法 。 也就是说 &#xff0c; 现实的漫游效果不是从摄像机的角度来看 &#xff0c; 但其仍然存在很多困难 。基于三维场景的视频融合 &#xff0c; 因其直观等特效在视频监控等相关领域有着…

Qt_day10_程序打包(完结)

目录 1. 设置图标 2. Debug和Release版本 3. 动态链接库 4. 打包 5. 联系项目要求 Qt开发的程序最终都是要给用户使用的&#xff0c;用户的电脑上不可能装一个Qt的开发环境导入项目使用。因此项目项目开发完成后需要打包——制作成安装包&#xff0c;用户直接下载并安装即可使用…

路径规划——RRT-Connect算法

路径规划——RRT-Connect算法 算法原理 RRT-Connect算法是在RRT算法的基础上进行的扩展&#xff0c;引入了双树生长&#xff0c;分别以起点和目标点为树的根节点同时扩展随机树从而实现对状态空间的快速搜索。在此算法中以两棵随机树建立连接为路径规划成功的条件。并且&…

【项目开发 | 跨域认证】JSON Web Token(JWT)

未经许可,不得转载。 文章目录 JWT设计背景:跨域认证JWT 原理JWT 结构JWT 使用方式注意JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理、结构及用法。 JWT设计背景:跨域认证 互联网服务的用户认证流程是现代应用中的核心组成部分,通常的流程…

学习笔记——PLCT:milk-v duo(持续更新)

买板子 官方标配有可能是单板&#xff08;如下图&#xff09;无工具包&#xff0c;记得买之前问一下客服。

Kubernetes-ArgoCD篇-01-简介

1、什么是Argo CD Argo CD 是针对 Kubernetes 的声明式 GitOps 持续交付工具。 Argo CD官方文档地址&#xff1a;https://argo-cd.readthedocs.io Argo CD源码地址&#xff1a;https://github.com/argoproj/argo-cd 1.1 关于Argo Argo是一个开源的项目&#xff0c;主要是扩…

【Python】轻松实现机器翻译:Transformers库使用教程

轻松实现机器翻译&#xff1a;Transformers库使用教程 近年来&#xff0c;机器翻译技术飞速发展&#xff0c;从传统的基于规则的翻译到统计机器翻译&#xff0c;再到如今流行的神经网络翻译模型&#xff0c;尤其是基于Transformer架构的模型&#xff0c;翻译效果已经有了质的飞…

父子线程间传值问题以及在子线程或者异步情况下使用RequestContextHolder.getRequestAttributes()的注意事项和解决办法

用到的工具类&#xff1a; Slf4j Configuration Lazy(false) public class SpringContextUtil{public static HttpServletRequest getRequest() {ServletRequestAttributes servletRequestAttributes (ServletRequestAttributes) RequestContextHolder.getRequestAttributes()…

FRTC8563实时时钟芯片的作用

FRTC8563是NYFEA徕飞公司推出的一款实时时钟芯片&#xff0c;采用SOP-8封装形式。这种封装形式具有体积小、引脚间距小、便于集成等特点&#xff0c;使得FRTC8563能够方便地应用于各种电子设备中&#xff0c;如&#xff1a;安防摄像机、监控摄像机、行车记录仪、车载电子等。 F…

怎么样绑定域名到AWS(亚马逊云)服务器

1&#xff0c;拿着你买的域名去亚马逊申请一个证书。申请证书分两种&#xff0c;一种是去亚马逊后台填域名手动申请 &#xff0c;另一种是通过API来申请&#xff0c;类似如下代码&#xff1a; 2、证验证书。有两种方式&#xff1a;一种是通过邮件&#xff0c;另一种去到域名提供…

从0开始深度学习(28)——序列模型

序列模型是指一类特别设计来处理序列数据的神经网络模型。序列数据指的是数据中的每个元素都有先后顺序&#xff0c;比如时间序列数据&#xff08;股票价格、天气变化等&#xff09;、自然语言文本&#xff08;句子中的单词顺序&#xff09;、语音信号等。 1 统计工具 前面介绍…

边缘计算在工业互联网中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 边缘计算在工业互联网中的应用 边缘计算在工业互联网中的应用 边缘计算在工业互联网中的应用 引言 边缘计算概述 定义与原理 发展…

蓝桥杯——杨辉三角

代码 package day3;public class Demo2 {public static void main(String[] args) {// TODO Auto-generated method stub// for (int i 0; i < 10; i) {// for (int j 0; j < 10; j) {// System.out.print("外&#xff1a;"i"内&#xff1a;&qu…

uniapp中多角色导致tabbar过多的解决方式

由于项目时间较紧张&#xff0c;找了很多却没找到特别合适的方法&#xff0c;最后使用了此方式。 一、自己封装tabbar组件 这里就不介绍怎么封装了&#xff0c;先说一下缺点&#xff1a; 1.跳转会有白屏问题&#xff08;并且搜了好多资料以及查看官网发现没有特别合适的方法…

【JVM】关于JVM的内部原理你到底了解多少(八股文面经知识点)

前言 &#x1f31f;&#x1f31f;本期讲解关于HTTPS的重要的加密原理~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废话不…

机器学习 ---模型评估、选择与验证(1)

目录 前言 一、为什么要有训练集与测试集 1、为什么要有训练集与测试集 2、如何划分训练集与测试集 二、欠拟合与过拟合 1、什么是欠拟合与欠拟合的原因 2、什么是过拟合与过拟合的原因 一些解决模型过拟合和欠拟合问题的常见方法&#xff1a; 解决过拟合问题&#…

第74期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

SpringBoot(八)使用AES库对字符串进行加密解密

博客的文章详情页面传递参数是使用AES加密过得,如下图所示: 这个AES加密是通用的加密方式,使用同一套算法,前端和后端都可以对加密之后的字符串进行加密解密操作。 目前线上正在使用的是前端javascript进行加密操作,将加密之后的字符串再传递到后端,PHP再进行解密操作。…

JavaScript逆向爬虫教程-------基础篇之JavaScript密码学以及CryptoJS各种常用算法的实现

目录 一、密码学介绍 1.1 为什么要学密码学?1.2 密码学里面学哪一些 二、字符编码三、位运算四、Hex 编码与 Base64 编码 4.1 Hex 编码4.2 Base64 编码 五、消息摘要算法 5.1 简介5.2 JS中的MD5、SHA、HMAC、SM3 六、对称加密算法 6.1 介绍6.2 加密模式和填充方式6.3 CryptoJ…