【算法】【回溯】N皇后问题【力扣-51】超详细的注释和解释手撕N皇后
【算法】【回溯】N皇后问题【力扣-51】超详细的注释和解释手撕N皇后
先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记关注我哦!️️️
在本篇文章中,博主先带大家复习一下回溯算法的三部曲,然后我们按照这个模板,手撕N皇后问题。
本篇建议收藏后食用~
这边博主提供题目的传送门,食用完这篇文章后大家可以通过传送门去力扣上答题51.N皇后-力扣。
题目描述

分析
思路:
我们先来看一下皇后的约束条件:
- 不能同行
- 不能同列
- 不能同斜线
很明显,皇后的位置是通过搜索出来的,每个位置进行搜索,因此,该题应使用回溯算法。
看到这里,先让我们复习一下回溯算法的模板:
- 确定回溯函数的返回值和参数(返回类型一般为void)
- 确定回溯函数的终止条件
- 确定回溯搜索的遍历过程
了解过回溯的伙伴都知道,回溯的搜索过程,都可以抽象成一棵树
接下来,博主用4x4棋盘将搜索过程展示给大家:
从图我们可以得知:矩阵高就是树的高度(或深度),矩阵宽就是树的宽度。
三部曲步骤详解
一:确定递归函数
定义全局变量的二维数组来统计结果,最后用push_back()往里面加东西就可以了
n是棋盘大小,row记录现在往第几行放皇后。
其实我们可以发现,row其实就是递归的深度,为什么不需要col?,因为col是同层搜索,row是控制搜索深度的。
vector<vector<string>>ret;
void backtracking(int n,int row,vector<string>&chessboard){}
二:确定递归的终止条件
很明显,什么时候递归结束?当row到最下面那一行的时候,也就是到树的最大深度n的时候结束
if(row==n){
ret.push_back(chessboard);
return;
}
三:确定单层搜索的逻辑
在每次确定好row之后,我们就要开始确定col,有了行和列,我们就可以确定皇后放置的位置。
for(int col=0;col<n;col++){
if(isValid(row,col,chessboard,n)){
chessboard[row][col]='Q';//放置皇后
backtracking(n,row+1,chessboard);
chessboard[row][col]='.';//回溯,撤销皇后
}
}
另外,我们要实现isValid()函数来判断,新皇后放置在(row,col)的位置,是否合法,合法我们才能放下去,如果不合法,进入下一次循环。
关于isValid()函数的实现,思路很简单,就是检查列,45°直线和135°直线即可。
为什么不用检查行:因为每次递归,只在每一行放一个皇后,放完就进入下一层了,所以行是肯定没问题的,不用检查。
整体代码实现
class Solution {
private:
vector<vector<string>> ret;
void backtracking(int n, int row, vector<string>& chessboard) {
//这里的row就像电话号码的字母组合那道题里面的index一样,是树的深度
//row代表现在递归到第几行了
if (row == n) {
ret.push_back(chessboard);
return;
}
for (int col = 0; col < n; col++) {
if (isValid(row, col, chessboard, n)) {
//皇后下在row,col的位置后,棋盘是否合法
chessboard[row][col] = 'Q';
backtracking(n, row + 1, chessboard);
chessboard[row][col] = '.';//回溯,撤销皇后
}
}
}
bool isValid(int row, int col, vector<string>& chessboard, int n) {
int count = 0;
//检查列--为什么不用检查行呢,因为每次递归,都只在一行放上一个,就到下一行了,所以每一行只有一个
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 >= 0; i--, j--) {
if (chessboard[i][j] == 'Q')
return false;
}
//检查135°直线上是否有皇后
for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
if (chessboard[i][j] == 'Q')
return false;
}
return true;
}
public:
vector<vector<string>> solveNQueens(int n) {
vector<string>chessboard(n, string(n, '.'));
backtracking(n, 0, chessboard);
return ret;
}
};
尾声
看到这里,相信伙伴们对这道经典的N皇后问题已经有了一定理解了。
最后,如果你感觉在这篇文章里学到东西的话,千千万万不要忘了点赞收藏关注后再离开哦!
【算法】【回溯】N皇后问题【力扣-51】超详细的注释和解释手撕N皇后的更多相关文章
- 力扣51. N 皇后(回溯法)
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子. n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 给你一个整数 n ,返回 ...
- 【算法】禁忌搜索算法(Tabu Search,TS)超详细通俗解析附C++代码实例
01 什么是禁忌搜索算法? 1.1 先从爬山算法说起 爬山算法从当前的节点开始,和周围的邻居节点的值进行比较. 如果当前节点是最大的,那么返回当前节点,作为最大值 (既山峰最高点):反之就用最高的邻居 ...
- 力扣算法题—051N皇后问题
#include "000库函数.h" //使用回溯法来计算 //经典解法为回溯递归,一层一层的向下扫描,需要用到一个pos数组, //其中pos[i]表示第i行皇后的位置,初始化 ...
- 【Warrior刷题笔记】力扣169. 多数元素 【排序 || 哈希 || 随机算法 || 摩尔投票法】详细注释 不断优化 极致压榨
题目 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/majority-element/ 注意,该题在LC中被标注为easy,所以我们更多应该关 ...
- 力扣算法经典第一题——两数之和(Java两种方式实现)
一.题目 难度:简单 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数, 并返回它们的数组下标. 你可以假设每种输入只会对应一 ...
- 力扣算法题—069x的平方根
实现 int sqrt(int x) 函数. 计算并返回 x 的平方根,其中 x 是非负整数. 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去. 示例 1: 输入: 4 输出: 2 示例 ...
- C++双指针滑动和利用Vector实现无重复字符的最长子串—力扣算法
题目: 力扣原题链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/ 给定一个字符串, ...
- 力扣算法——135Candy【H】
老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分. 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果.相邻的孩子中,评分高 ...
- N 皇后-力扣解题
n 皇后问题 研究的是如何将 n 个皇后放置在 n*n 的棋盘上,并且使皇后彼此之间不能相互攻击. 给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案. 每一种解法包含一个不同的 n 皇后问 ...
- LeetCode 1244. 力扣排行榜
地址 https://www.acwing.com/solution/LeetCode/content/5765/ 题目描述新一轮的「力扣杯」编程大赛即将启动,为了动态显示参赛者的得分数据,需要设计一 ...
随机推荐
- OpenSCA用开源的方式做开源风险治理:Why? What? How?
随着容器.微服务等新技术的快速迭代,开源软件已成为业界主流形态,开源和云原生时代的到来导致软件供应链越来越趋于复杂化和多样化,网络攻击者开始采用软件供应链攻击作为击破关键基础设施的的重要突破口,从而导 ...
- 三、mycat实验数据
系列导航 一.Mycat实战---为什么要用mycat 二.Mycat安装 三.mycat实验数据 四.mycat垂直分库 五.mycat水平分库 六.mycat全局自增 七.mycat-ER分片 最 ...
- C#设计模式17——责任链模式的写法
是什么: 责任链模式是一种行为型设计模式,它允许对象组成一个链并依次检查另一个对象是否可以处理请求.如果一个对象可以处理请求,它处理请求,并且负责将请求传递给下一个对象,直到请求被处理为止. 为什么: ...
- 搬运 |(有刀🔪慎入)kwdnx、谷雨、更漏与我
本打算把文案投到官微,但官微说文案太长了,只能放删减版: 那就把文案放博客上吧 写于 癸卯年 戊午月 己亥日. 四年前的冬天我们初见,大家都是青涩的未成年人:在少年班团建的喧闹中,谷雨谈论高数竞赛,k ...
- spring启动流程 (1) 流程概览
本文将通过阅读AnnotationConfigApplicationContext源码,分析Spring启动流程. 创建AnnotationConfigApplicationContext Annot ...
- 【转】获取本地图片的URL
在写博客插入图片时,许多时候需要提供图片的url地址.作为菜鸡的我,自然是一脸懵逼.那么什么是所谓的url地址呢?又该如何获取图片的url地址呢? 首先来看一下度娘对url地址的解释:url是 ...
- ChatGPT-NextWeb部署和调试打造属于自己的GPT
首先我关注这个项目有一段时间了,不得不说作者和他的社区真的很猛! 首先这个项目截至目前已经有了40.9K的Start了,Fork也已经有了38.1K了,这个数据真的超级牛批了. 那么我们来看一下这款号 ...
- MySQL高可用搭建方案之(MMM)
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 注意:这篇转载文章,非原创 首发博客地址 原文地址 前言 MySQL的高可用 ...
- [转帖]rsync原理
简介: Rsync(remote synchronize)是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件.Rsync使用所谓的"Rsync算法"来使本地和远 ...
- [转帖]一个轻量的Linux运维监控脚本
https://zhuanlan.zhihu.com/p/472040635 写在前面 我的需求 嗯,有几台很老的机器,上面部署的几个很老的应用 我需要每周对机器上的一些内存,磁盘,线程,应用和数据库 ...
