✔️本文主题:回溯算法之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皇后?——详细图解!相关推荐

  1. AIGC:Stable Diffusion(一项普通人就能实现的AI前沿科技)的简介、Stable Diffusion2.0的改进、安装、使用方法(文本到图像/图像修改/超分辨率/图像修复)之详细攻略

    AIGC:Stable Diffusion(一项普通人就能实现的AI前沿科技)的简介.Stable Diffusion2.0的改进.安装.使用方法(文本到图像/图像修改/超分辨率/图像修复)之详细攻略 ...

  2. 网络中超难的75道逻辑题及答案

    网络中超难的75道逻辑题及答案 [1]假设有一个池塘,里面有无穷多的水.现有2个空水壶,容积分别为5升和6升.问题是如何只用这2个水壶从池塘里取得3升的水. 由满6向空5倒,剩1升,把这1升倒5里,然 ...

  3. 美国计算机加音乐专业,美国留学:原来这就是传说中炫酷到炸裂的电子音乐制作专业...

    原标题:美国留学:原来这就是传说中炫酷到炸裂的电子音乐制作专业 关注我们获得更多精彩内容 电子音乐制作又名MIDI(Musical Instrument Digital Interface)制作,是九 ...

  4. CVPR 2020 SLAM挑战赛冠军方案解读,搞定超难数据集TartanAir

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨R 来源丨旷视研究院 编辑丨极市平台 导读 在CVPR 2020 SLAM挑战赛上,旷视研究院参 ...

  5. 超详细图解!【MySQL进阶篇】存储过程,视图,索引,函数,触发器

    超详细图解![MySQL进阶篇]存储过程,视图,索引,函数,触发器 1.1 下载Linux 安装包 1.2 安装MySQL 1.3 启动 MySQL 服务 1.4 登录MySQL 2\. 索引 2.1 ...

  6. 超大超详细图解,让你掌握Spark memeoryStore内存管理的精髓

    摘要:memoryStore主要是将没有序列化的java对象数组或者序列化的byteBuffer放到内存中. 本文分享自华为云社区<spark到底是怎么确认内存够不够用的?超大超详细图解!让你掌 ...

  7. 难道这就是传说中的PR劫持吗?爱商网2ec.cn

    难道这就是传说中的PR劫持吗?爱商网2ec.cn 新买一个域名,2ec.cn,自己认为还不错,做商务网,取名爱商网,买之前还是PR0,刚刚交易完毕第2天,发现PR竟然更新到8,窃喜中.之前一直对PR劫 ...

  8. 超级坦克大战1990 - 坦克大战超难版

    [简介] 还记得小时玩的坦克大战1990吗,<超级坦克大战1990>在优化其普通模式的基础上,新增了更加华丽炫酷的超级模式,还加入了更加刺激.更加困难的挑战模式,各种超难的关卡等着你来挑战 ...

  9. excel做地图热力图_来来来,这就是传说中的Excel热力图!

    Hey,大家好,我是ExcelHome学院图表之美培训班的讲师三土. 欢迎大家来到爱说川普的三土给大家带来的实用型图表,想要兼顾美观又能不失实用价值得图表么?让三土来帮你. (本教程使用Excel版本 ...

最新文章

  1. 青少年python编程课_青少年之Python编程课程安排第一季
  2. 大数据背景下的高职院校信息化建设探索
  3. 【Groovy】闭包 Closure ( 闭包中调用 Groovy 脚本中的方法 | owner 与 delegate 区别 | 闭包中调用对象中的方法 )
  4. JAVA 基本运算符(摘)
  5. Qt Creator使用Clang代码模型解析C ++文件
  6. jdbc mysql 存储过程查询数据_JDBC连接(MySql)数据库步骤,以及查询、插入、删除、更新等十一个处理数据库信息的功能。...
  7. 【算法分析与设计】查找第K大/小元素问题
  8. 微信开发博客——柳峰
  9. Bootstrap导航组件
  10. springboot+JPARepository实现增删改查
  11. SQL数据库的查询操作大全(select)
  12. Unity5.0 Shader 极简入门(一)
  13. Linux Deploy 2.0 中文,Linux Deploy:在Android上部署Linux
  14. nodejs实现微博第三方登录
  15. Apache详解(一)Internet和HTTP协议
  16. 黑客帝国角色 之 先知的另类解读
  17. ACCESS实例2 资料管理1——表、表关系与查询
  18. teamviewer14 去商用途提示
  19. mysql-使用Navicat导出sql查询数据
  20. easyuefi如何添加引导_easyuefi怎么用?easyuefi基本使用方法介绍

热门文章

  1. javascript_JavaScript已经赢了
  2. 百度快照被劫持 快速恢复快照的解决办法
  3. Unity 引导动画的制作
  4. RHEL / CentOS 配置epel源
  5. 关于OleDbParameter的困扰
  6. 导览Linux 文件系统类型
  7. datart 问题总结
  8. 微服务版单点登陆系统(SSO)实践
  9. dnscrypt-proxy+dnsmasq搭建无污染DNS服务器
  10. 12款最强辅助IDEA插件,助力新手程序员