【经典算法】N皇后问题

article/2025/10/6 3:36:09

✨前言✨

        N皇后问题经典的解决方案是暴力递归,其时间复杂度是O(2^n),因此常用来测试计算机的算力。今天我会给大家带来经典方法的详解,也会给大家展示N皇后优化后的大神解法。做一道经典题目,来一场思维旅行。


目录

✨前言✨

💡题目:

🔑传统解法:

代码示例:

大神解法:



💡题目:

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

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

力扣题目链接:  N皇后问题


🔑传统解法:

N皇后的传统解法是暴力递归,在我看来暴力递归的精髓就是尝试,N皇后问题要求任意两个皇后都不共行,不共列,不共斜线。因此在一个N*N的棋盘上放N个皇后,因此可以看成由上到下每一行放一个皇后的尝试模型。

为了更形象的解决这一问题,我们先来看一下图:(来自力扣)

       因为我们尝试模型是遍历每一行,每一行尝试放一个皇后,所以所有皇后一定不共行,只需保证在尝试第i个皇后时,第i个皇后与第i-1个皇后不共列,不共斜线,因此我们应该在尝试0-i-1个皇后时,记录下其位置,这样在放第i个皇后时,就可以根据之前所有已经放好的皇后决定第i个皇后应该放哪里。

所以设计的递归函数的参数有三个:

     1:变量i表示现在在尝试第i行放第i个皇后

     2:变量n表示要放皇后的总数,是一个固定的值,用来标记递归终止条件。

     3:数组 result[i] 记录已经放好的皇后在哪一行哪一列,表示第i个皇后所在的列数。

代码示例:

    //暴力递归:N皇后问题的朴素解法//1:当你处理第i行时,我们默认[0...i-1]的皇后都有效摆好了//2:当你摆第i个皇后时,你只需要考虑i个皇后与其它i-1个皇后不共列和不共斜线//三个参数:record[i] 记录下第i个皇后所在的列数//int n表示是几阶皇后问题//int i表示当前处理到了哪一阶public static int process1(int i,int n,int[] record){if(i==n){//当i等于n时,说明N个皇后全部摆放完毕,此时应返回一种解法return 1;}int res=0;//现在轮到摆第i个皇后,//通过遍历第i行的每一列试探每一个位置是否能放皇后for(int j=0;j<n;j++){if(isValid(record,i,j)){//通过isValid函数来判断这个位置是否能放皇后record[i]=j;res+=process1(i+1,n,record);}}return  res;}public static boolean isValid(int[] record,int i,int j){//判断逻辑:如果这个位置与之前的i-1个皇后同列或者共斜线则不能放皇后for(int k=0;k<i;k++){//判断共列以及共斜线if(record[k]==j||(Math.abs(k-i)==Math.abs(record[k]-j))){return false;}}return true;}

大神解法:

我们可以通过位运算来加速算法的常数时间操作。

//n皇后问题大神解法//利用位运算加速,虽然时间复杂度任然是O(2^n)但是其常数时间要低的多//思路:默认每一次递归都能在每一行正确放置一个皇后//这种N皇后的效率比朴素解法要高//limit 范围限制  例如8皇后问题,那么其二进制序列的后8位全是1,左边其他位全是无效位//colLim 列限制   二进制序列中为0的地方标志这一列还没有放过皇后,如果是1表示这一列已经放了皇后//leftDiaLim左斜线限制    表示由于放了0-i-1个皇后,而导致在放第i个皇后时,由于左斜线限制,//                      使得第i行不能放皇后的列全标记为1//rightDiaLim 右斜线限制  同理public static int quickNQueue(int N){if(N<1||N>32){//因为int最多32个字节,超过32皇后问题要把in改成longreturn 0;}int limit=N==32?-1:(1<<N)-1;//定义出limit n皇后问题则limit的后n为全是1其他为全为0return process2(limit,0,0,0);}//因为我们要用位运算来加速,因此递归函数所有整型参数都应该看成0-1构成的序列public static int process2(int limit,int colLim,int leftDiaLim,int rightDiaLim){if(colLim==limit){return 1;}int res=0;int pos=limit&(~(colLim|leftDiaLim|rightDiaLim));//在范围内可以放皇后的位置全标记位1int mostRightOne=0;while(pos!=0){//摆第i个皇后逻辑//在pos中二进制序列为1的位置能放皇后,我们每一次取最右侧的1位置放皇后mostRightOne=pos&(~pos+1);//拿出最右侧的一个1其它位全变成0,并在这个位置放皇后pos-=mostRightOne;//pos最右侧为1的位置改成0,说明这个位置已经放了皇后//更新参数直接递归摆剩下所有的皇后res+=process2(limit,colLim|mostRightOne,//这一列已经放了皇后,标记为1(leftDiaLim|rightDiaLim)<<1,//更新这个皇后的左斜线限制(rightDiaLim|mostRightOne)>>>1//更新这个皇后的右斜线限制);}return res;}

一道练习题:

做一道题目来巩固所学知识吧!

力扣链接:剑指offer 8皇后问题


由于本人水平十分有限,若有错误请即使告知!如果有帮助别忘了,万分感谢。

点赞👍         收藏✨    关注✌


http://chatgpt.dhexx.cn/article/oSPAGGVu.shtml

相关文章

n皇后问题(回溯法)(超易理解)(详细注释)

问题&#xff1a; N皇后问题是一个经典的问题&#xff0c;描述如下&#xff1a; 在的方格棋盘需要放置N个皇后&#xff0c;使得它们不相互攻击&#xff0c; 即任意2个皇后不允许处在同一排&#xff0c;同一列&#xff0c;也不允许处在与棋盘边框成45度角的斜线上。 对于给定的N…

n皇后问题(回溯法)

目录 1.问题描述 2.问题分析 3.完整源码 1.问题描述 八皇后问题是十九世纪著名的数学家高斯于1850年提出的。问题是:在88的棋盘上摆放八个皇后&#xff0c;使其不能互相攻击&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上。可以把八皇后问题扩展到n皇后问…

【浏览器跨域】跨域访问接口浏览器怎么设置?

window系统 1、右键浏览器&#xff0c;点击属性 2、找到目标&#xff0c;目标输入框内容最后面加上 --disable-web-security --user-data-dirC:\MyChromeDevUserData&#xff0c;–user-data-dir 3、点击确定 4、重新打开浏览器即可 mac系统 终端输入&#xff0c;重新打开浏…

AJAX跨域访问(不同域之间相互访问)

目录 一、跨域&#xff1a;二、同源策略&#xff1a;三、解决Ajax跨域问题的方案&#xff1a;方案一&#xff1a;设置响应头方案二&#xff1a;jsonp方案三&#xff1a;jQuery封装jsonp方案四&#xff1a;代理机制&#xff08;httpclient&#xff09;方案五&#xff1a;nginx反…

nginx配置图片跨域访问

在server段中添加红框内的图片跨域内容 参数 location ~* .*.(gif|jpg|jpeg|png|bmp|swf)$ { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Headers X-Requested-With; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS…

浏览器跨域访问限制

一.什么是跨域 广义的跨域&#xff1a; (1) 资源跳转&#xff1a;A链接、重定向、表单提交 (2) 资源嵌入&#xff1a;<link>、<script>、<img>、<frame>等dom标签&#xff0c;还有样式中background:url()、font-face()等文件外链 (3) 脚本请求&#x…

Django 多方式实现跨域访问

一、什么是跨域 1.1 跨越介绍 跨域&#xff0c;是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的&#xff0c;是浏览器对JavaScript实施的安全限制。 这里说明一下&#xff0c;无法跨域是浏览器对于用户安全的考虑&#xff0c;如果自己写个没有同源策略的浏览…

Flask中跨域访问的实现

在我们访问不同的服务器时&#xff0c;就会涉及到了跨域的问题。因为不同域名之间是无法进行交流的&#xff0c;然后跨域就打破了这种规则的限制。说起Flask中的跨域&#xff0c;就不得不提到CORS组件了&#xff0c;相信大家在其它框架中也见过了它的身影。下面我们就跨域问题和…

Tomcat设置允许跨域访问

开发React项目时前端通过axios向后端代码发起请求调试的时候由于后端代码运行在8080端口而React项目运行在3000端口导致浏览器的同源策略禁止跨域请求&#xff0c;因此需修改Tomcat配置文件web.xml以开放跨域访问。 在tomcat的web.xml文件末尾加上&#xff1a; <filter>…

express 允许跨域访问

设置Express const express require(express) const bodyParser require(body-parser)const app express() // 处理参数 app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false }));// 设置允许跨域访问该服务 app.all(*, function (req, res, nex…

tomcat 设置允许跨域访问

既然想到使用tomcat进行跨域的设置&#xff0c;而不使用在项目中设置header来解决&#xff0c;说明你也是tomcat 下的资源需要做跨域处理吧&#xff1f;这也是一个统一的允许跨域设置&#xff0c;tomcat下的所有请求都将放开&#xff0c;请注意。 具体步骤&#xff1a; 1.首先…

Chrome浏览器 设置跨域访问

由于浏览器的安全策略&#xff0c;不同域名的访问会被限制&#xff0c;导致不能访问 chorme或者360都可以使用下列设置来解决这个问题&#xff1a; &#xff08;1&#xff09;在电脑上新建一个目录&#xff0c;例如&#xff1a;C:\MyChromeEnvUserData &#xff08;2&#x…

tomcat9配置允许跨域访问

目录 一、问题描述二、解决办法三、程序截图 一、问题描述 最近在用Tomcat9最新版本部署程序的时候&#xff0c;发现其他服务访问我的静态资源的时候出现了跨域访问&#xff0c;结果很明显被拦截了&#xff0c;之前的文章介绍了Tomcat8.5的跨域配置&#xff0c;但是研究发现&a…

html的页面怎样直接跨域访问,【HTML】iframe跨域访问问题

概述 本地同一浏览器访问本地HTML文件和访问服务器端HTML文件,本地Iframe没有自适应高度,而服务器端的Ifrane自适应了高度。 1.问题重现: Chrome 版本 41.0.2272.101 (64-bit) OS:Win8.1 Chrome访问服务器端HTML文件呈现的结果 Chrome访问本地HTML文件呈现的结果 本地访问的…

vue跨域访问

vue跨域访问的问题&#xff08;基于允许跨域访问的前提&#xff09; 找到“ vue.config.js"&#xff0c;有些不是vue.config.js命名&#xff0c;也就是找到重写路径的js文件。重写一下自己要替换的路径&#xff0c;在原有基础上加一个 新建一个dev.js文件内容如下&#…

关于跨域访问

1 概念 2 案例 3 解决 4 实现 5 什么是跨域问题 示意图 1 概念 跨域访问&#xff0c;是指从一个域名的网页去请求另一个域名的资源。比如从 www.baidu.com 页面去请求 ww w.google.com 的资源。 但是一般情况下不能这么做跨域访问&#xff0c;因为有浏览器的 “ 同源策略…

什么是跨域?如何实现跨域访问?

跨域是指不同域名之间相互访问。 JavaScript同源策略的限制&#xff0c;A域名下的JavaScript无法操作B或是C域名下的对象 实现&#xff1a; 1、JSONP跨域&#xff1a;利用script脚本允许引用不同域下的js实现的&#xff0c;将回调方法带入服务器&#xff0c;返回结果时回调 2、…

跨域访问

跨域访问是什么 同源策略 1995年&#xff0c;同源政策由Netscape公司引人浏览器。目前&#xff0c;所有刘览器都实行这个政策。同源政策的目的&#xff0c;是为了保证用户信息的安全&#xff0c;防止恶意的网站窃取数据。随着互联网的发展&#xff0c;“同源政策”越来越严格…

朴素贝叶斯分类器python_python实现高斯朴素贝叶斯分类器

在这篇文章中,我们将使用我最喜欢的机器学习库scikit-learn在Python中实现朴素贝叶斯分类器。接下来,我们将使用经过训练的朴素贝叶斯(监督分类法)模型来预测人口收入。 在朴素贝叶斯分类器的文章中我们讨论了贝叶斯定理,我们希望你对贝叶斯定理的基础知识有一定的了解,如果…

贝叶斯分类器(matlab)

目标 下表由雇员数据库的训练数据组成。数据已泛化。例如&#xff0c;age“3135”表示年龄在31~35之间。对于给定的行&#xff0c;count表示department、status、age和salary在该行具有给定值的元组数。 DepartmentStatusAgeSalaryCountSalesSenior31-3546K-50K30Salesjunior…