这就是传说中超难的N皇后?——详细图解!
✔️本文主题:回溯算法之N皇后 算法
✔️题目链接:N皇后
详解N皇后
- 一、前言
- 二、题目信息
- 三、解题思路
- 四、参考代码
- 五、结语
一、前言
大家好久不见,今天我们一起来学习一道很经典、也很有难度的一道题目——N皇后
二、题目信息
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间 不能
相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
说白了,这道题题目就是让所有皇后之间不在同一行、同一列、同一对角线,求出所有满足此要求的棋盘!
如图示,左边3X3的样例就是不符合要求的!!!我们要收集 所有
像4X4这样的样例!!!
三、解题思路
思路分析
一看到这道题目,我们会很自然想要用暴力算法来解决,例如设置一个for循环来遍历第一行、再来一个for循环遍历第二行…依此类推。
暴力算法当然是可以解决这道题目的,但这里就会有一个问题,3X3的棋盘我们套3个循环,那4X4的棋盘呢?5X5的又怎么办呢?
因此我们用暴力循环其实是不太适合这道题目的,因为我们没法控制每次套几个循环,那有没有一种方式能够让我们控制有几个for循环呢?
答案是有的!!!看过上次讲解的小伙伴应该知道,回溯算法恰好是用来实现多重for循环的一个算法,他本质上也是一个暴力算法,回溯算法基础 。
我们按照暴力算法的思路先来分析一下:
核心思路就是:定住第一行的一个元素,然后去下一行定住一个元素,再去下一行定住一个元素,直到底行。
画图表示:
因为图片大小原因,我只把中间过程的某一步完全画了出来,大家明白暴力算法的思路即可。
那么怎么实现我们这个 可变for循环
呢,是的,就是使用 回溯算法
!
之前说过,回溯算法本质也是暴力算法,他通过递归的方式来实现多重for循环,从而解决暴力算法无法设计多重循环的问题,那按照回溯算法的基本思路,我们一起来设计一下!!
✔️递归终止条件
什么时候棋盘放下了所有皇后,什么时候就停止递归,啥时候所有皇后都放下了?当然是最后一层for循环也走完了的时候。
这里我再简单补充一句:为什么是for循环走完才证明皇后全都放下了?之前放完皇后不行吗
不要忘记规则的约束,同一行或同一列或同一斜线上的皇后会相互攻击,如果你把两个皇后放到同一行,直接就不符合规则了,
因此一行放且必须放一个!!!
✔️每一层的处理逻辑
如果不在最终层,我们就要用递归的思路去实现多重for循环!
for(int i=0;i<n;i++)
{chessboard[row][rol] = 'Q'; //确定好这一层的一个皇后backtracking();//递归此函数,继续向下执行相同逻辑chessboard[row][rol] = '.'; //将刚刚确定好的皇后剔除,换成下一个}
固定好一个元素,要去递归执行下一层了,当满足收集结果的条件后,递归结束,再将棋盘上的皇后剔除,固定下一个元素继续执行相同的逻辑。
能够跳回原来的状态,这就是回溯算法的精髓。
✔️收集结果
当我们进入最终层,就要准备收集结果了,并非所有棋盘都需要收集,我们只需要收集 满足 皇后同一行或同一列或同一斜线上
的棋盘,因此我们需要判断棋盘是否符合要求!
但要把所有情况都算出再来检查就会产生大量时间浪费和代码冗余,因此我们采用放皇后时,就检查棋盘是否符合要求
,如果不符合,直接进行下一次循环!
要检查当前位置可不可以放置皇后,需要满足三个条件
针对以上三种情况,我们写一个简单函数:
bool CheckBoard(vector<string>& chessboard,int row,int col,int n)
{//此函数判断第row行第rol列能不能放皇后//同一列for (int i = 0;i<row;i++){if (chessboard[i][col] == 'Q'){return false;}}//45°for (int i = row - 1, j = col + 1; i >= 0 && j < n ;i--,j++){if (chessboard[i][j] == 'Q'){return false;}}//135°for (int i = row-1,j = col-1;i>=0 && j>=0;i--,j--){if (chessboard[i][j] == 'Q'){return false;}}return true;}
四、参考代码
class Solution {public:vector<vector<string>> result;void backtracking(int n, int row, vector<string>& chessboard) {if (row == n) {result.push_back(chessboard);//收集合法的结果,只有合法才能来到最后!!!return;}for (int col = 0; col < n; col++) //行固定了,列开始回溯!!{if (CheckBoard(chessboard,row, col, n)) { // 验证合法就可以放chessboard[row][col] = 'Q'; // 放置backtracking(n, row + 1, chessboard);//去遍历下一层!!chessboard[row][col] = '.'; // 撤销}}}bool CheckBoard(vector<string>& chessboard,int row,int col,int n){//此函数判断第row行第rol列能不能放皇后//同一列for (int i = 0;i<row;i++){if (chessboard[i][col] == 'Q'){return false;}}//45°for (int i = row - 1, j = col + 1; i >= 0 && j < n ;i--,j++){if (chessboard[i][j] == 'Q'){return false;}}//135°for (int i = row-1,j = col-1;i>=0 && j>=0;i--,j--){if (chessboard[i][j] == 'Q'){return false;}}return true;}vector<vector<string>> solveNQueens(int n) {vector<string> chessboard(n, string(n, '.'));backtracking(n, 0, chessboard);return result;}
};
五、结语
回溯算法是一种很神奇的算法,他能通过递归来实现多重for循环,从而将复杂的问题解除,虽然本质上他还是暴力算法,但对于全排列、N皇后这类问题,能解出答案就已经很不错了~
如果你感觉有所收获,可以点赞 + 收藏 +关注 支持一下蓝色学者哦~ 我们下次见~
这就是传说中超难的N皇后?——详细图解!相关推荐
- AIGC:Stable Diffusion(一项普通人就能实现的AI前沿科技)的简介、Stable Diffusion2.0的改进、安装、使用方法(文本到图像/图像修改/超分辨率/图像修复)之详细攻略
AIGC:Stable Diffusion(一项普通人就能实现的AI前沿科技)的简介.Stable Diffusion2.0的改进.安装.使用方法(文本到图像/图像修改/超分辨率/图像修复)之详细攻略 ...
- 网络中超难的75道逻辑题及答案
网络中超难的75道逻辑题及答案 [1]假设有一个池塘,里面有无穷多的水.现有2个空水壶,容积分别为5升和6升.问题是如何只用这2个水壶从池塘里取得3升的水. 由满6向空5倒,剩1升,把这1升倒5里,然 ...
- 美国计算机加音乐专业,美国留学:原来这就是传说中炫酷到炸裂的电子音乐制作专业...
原标题:美国留学:原来这就是传说中炫酷到炸裂的电子音乐制作专业 关注我们获得更多精彩内容 电子音乐制作又名MIDI(Musical Instrument Digital Interface)制作,是九 ...
- CVPR 2020 SLAM挑战赛冠军方案解读,搞定超难数据集TartanAir
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨R 来源丨旷视研究院 编辑丨极市平台 导读 在CVPR 2020 SLAM挑战赛上,旷视研究院参 ...
- 超详细图解!【MySQL进阶篇】存储过程,视图,索引,函数,触发器
超详细图解![MySQL进阶篇]存储过程,视图,索引,函数,触发器 1.1 下载Linux 安装包 1.2 安装MySQL 1.3 启动 MySQL 服务 1.4 登录MySQL 2\. 索引 2.1 ...
- 超大超详细图解,让你掌握Spark memeoryStore内存管理的精髓
摘要:memoryStore主要是将没有序列化的java对象数组或者序列化的byteBuffer放到内存中. 本文分享自华为云社区<spark到底是怎么确认内存够不够用的?超大超详细图解!让你掌 ...
- 难道这就是传说中的PR劫持吗?爱商网2ec.cn
难道这就是传说中的PR劫持吗?爱商网2ec.cn 新买一个域名,2ec.cn,自己认为还不错,做商务网,取名爱商网,买之前还是PR0,刚刚交易完毕第2天,发现PR竟然更新到8,窃喜中.之前一直对PR劫 ...
- 超级坦克大战1990 - 坦克大战超难版
[简介] 还记得小时玩的坦克大战1990吗,<超级坦克大战1990>在优化其普通模式的基础上,新增了更加华丽炫酷的超级模式,还加入了更加刺激.更加困难的挑战模式,各种超难的关卡等着你来挑战 ...
- excel做地图热力图_来来来,这就是传说中的Excel热力图!
Hey,大家好,我是ExcelHome学院图表之美培训班的讲师三土. 欢迎大家来到爱说川普的三土给大家带来的实用型图表,想要兼顾美观又能不失实用价值得图表么?让三土来帮你. (本教程使用Excel版本 ...
最新文章
- 青少年python编程课_青少年之Python编程课程安排第一季
- 大数据背景下的高职院校信息化建设探索
- 【Groovy】闭包 Closure ( 闭包中调用 Groovy 脚本中的方法 | owner 与 delegate 区别 | 闭包中调用对象中的方法 )
- JAVA 基本运算符(摘)
- Qt Creator使用Clang代码模型解析C ++文件
- jdbc mysql 存储过程查询数据_JDBC连接(MySql)数据库步骤,以及查询、插入、删除、更新等十一个处理数据库信息的功能。...
- 【算法分析与设计】查找第K大/小元素问题
- 微信开发博客——柳峰
- Bootstrap导航组件
- springboot+JPARepository实现增删改查
- SQL数据库的查询操作大全(select)
- Unity5.0 Shader 极简入门(一)
- Linux Deploy 2.0 中文,Linux Deploy:在Android上部署Linux
- nodejs实现微博第三方登录
- Apache详解(一)Internet和HTTP协议
- 黑客帝国角色 之 先知的另类解读
- ACCESS实例2 资料管理1——表、表关系与查询
- teamviewer14 去商用途提示
- mysql-使用Navicat导出sql查询数据
- easyuefi如何添加引导_easyuefi怎么用?easyuefi基本使用方法介绍