力扣日记3.6-【回溯算法篇】51. N 皇后

力扣日记:【回溯算法篇】51. N 皇后

日期:2023.3.6
参考:代码随想录、力扣

51. N 皇后

题目描述

难度:困难

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

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

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

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。

示例 1:
在这里插入图片描述

输入:n = 4
输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

示例 2:

输入:n = 1
输出:[[“Q”]]

提示:

  • 1 <= n <= 9

题解

cpp ver
class Solution {
public:vector<vector<string>> result;vector<vector<string>> solveNQueens(int n) {// 初始化 棋盘// 注意对于一个二维矩阵,board[row][col] 即索引是先row再colvector<string> chessboard(n, string(n, '.'));   backtracking(chessboard, n, 0);return result;}bool isValid(vector<string> chessboard, int n, int x, int y) {  // y -> row, x -> col,索引先y再x// 同一行是否有Q(由于是递归进入下一行,所以不可能在同一行有Q,不需判断)// 同一列是否有Q(由于是从上往下遍历,所以下方未遍历过的行不可能有Q,只需判断当前位置以上的部分)for (int i = 0; i < y; i++) {if (chessboard[i][x] == 'Q') return false;}// \ 是否有Q(同理,只需判断左上,注意m,k从当前位置的左上一个位置开始)for (int m = x - 1, k = y - 1; m >= 0 && k >= 0; m--, k--) { // m 为 横坐标,k 为纵坐标 查询:[0,x-1) [0,y-1)if (chessboard[k][m] == 'Q') return false;}// / 是否有Q(同理,只需判断右上,注意m,k从当前位置的右上一个位置开始)for (int m = x + 1, k = y - 1; m < n && k >= 0; m++, k--) { // [x+1, n) [0,y-1)if (chessboard[k][m] == 'Q') return false;}return true;}// 关键:将N皇后问题转换为树形结构:横向搜索为for循环,纵向遍历(进入下一行)为递归// 参数:棋盘矩阵,皇后数,当前遍历到的行数void backtracking(vector<string>& chessboard, int n, int row) {// 终止条件:row从0开始,当为n时,说明已经遍历完所有行if (row == n) {result.push_back(chessboard);return;}// for 循环for (int i = 0; i < n; i++) {   // 每一行都从0开始遍历if (isValid(chessboard, n, i, row)) {// 如果当前位置为有效位置// 设置此位置为皇后位置chessboard[row][i] = 'Q';// 递归(进入下一行)backtracking(chessboard, n, row + 1);   // row 作为参数,自动回溯// 回溯chessboard[row][i] = '.';}}}   
};

复杂度

时间复杂度: O(n!)
空间复杂度: O(n)

思路总结

  • 第一次接触到N皇后,即使知道用回溯法,还是不知道如何下手。再次感谢代码随想录提供思路。
  • 关键思路:
    • 将N皇后问题转换为树形结构:依次遍历棋盘的各个位置,横向搜索通过for循环,纵向遍历(进入下一行)通过递归

      棋盘的宽度就是for循环的长度,递归的深度就是棋盘的高度

    • 只有当前位置有效,才能放入棋盘(处理节点)并进行递归回溯

  • 难点(易错):判断当前位置是否有效
    • 首先要明确,对于二维数组,row为第一个索引,col为第二个索引
    • 判断当前位置是否有效,即当前位置的同一行、同一列、左45°、右45°(同斜线)均不能出现皇后’Q’
    • 剪枝:由于遍历是从左到右、从上往下(一行接一行)遍历,所以在判断时:
      • 对于同一行是否有Q:由于是递归进入下一行,所以不可能在同一行有Q,不需判断
      • 对于同一列是否有Q:由于是从上往下遍历,所以下方未遍历过的行不可能有Q,只需判断当前位置以上的部分
      • 对于 \ 方向是否有Q:同理,只需判断左上,注意m(横坐标),k(纵坐标)从当前位置的左上一个位置开始,即m:x-1 → 0,k:y-1 → 0;
      • 对于 / 方向是否有Q:同理,只需判断右上,注意m,k从当前位置的右上一个位置开始,即 m:x+1 → n - 1,k:y -1 → 0。
  • 三部曲:
    • 参数: 棋盘矩阵,皇后数,当前遍历到的行数
      • 棋盘的初始化:
        vector<string> chessboard(n, string(n, '.'));
        
    • 终止条件:row从0开始,当为n时,说明已经遍历完所有行,则终止
    • for 循环
      • 对棋盘的第row行,从棋盘左遍历到右
      • 如果当前位置有效,则进行:
        • 处理节点即放下皇后(chessboard[row][i] = 'Q';
        • 递归(进入下一行)
        • 回溯(chessboard[row][i] = '.';
  • 树状结构示意图(n = 3)
    • 在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能工具管理系统-智能工具柜系统

智能工具可视化管理系统(智工具DW-S308)是依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID工具进行统一管理、分析的信息化、智能化、规范化的系统。 一、工具管理现状 东识RFID工具管理系统是一种便捷化的工具管理系统&#xff0c;它采用RFID技…

一篇搞懂什么是LRU缓存|一篇搞懂LRU缓存的实现|LRUCache详解和实现

LRUCache 文章目录 LRUCache前言项目代码仓库什么时候会用到缓存(Cache)缓存满了&#xff0c;怎么办&#xff1f;什么是LRUCacheLRUCache的实现LRUCache对应的OJ题实现LRUCache对应的STL风格实现 前言 这里分享我的一些博客专栏&#xff0c;都是干货满满的。 手撕数据结构专栏…

【UE5】游戏框架GamePlay

项目资源文末百度网盘自取 游戏框架 游戏 由 游戏模式(GameMode) 和 游戏状态(GameState) 所组成 加入游戏的 人类玩家 与 玩家控制器(PlayerController) 相关联 玩家控制器允许玩家在游戏中拥有 HUD&#xff0c;这样他们就能在关卡中拥有物理代表 玩家控制器还向玩家提供 …

Spring boot 请求参数包含[]等特殊字符,导致无法接收问题

前言对字符进行转义修改tomcat 配置 前言 Spring boot 请求参数包含[]等特殊字符&#xff0c;导致无法接收问题 对字符进行转义 中括号[] 必须用%5B%5D转义&#xff0c;否则tomcat无法解析&#xff0c;回抛出不合法字符异常&#xff0c;不会进入控制器 修改tomcat 配置 p…

安信可IDE(AiThinker_IDE)编译ESP8266工程方法

0 工具准备 AiThinker_IDE.exe ESP8266工程源码 1 安信可IDE&#xff08;AiThinker_IDE&#xff09;编译ESP8266工程方法 1.1 解压ESP8266工程文件夹 我们这里使用的是NON-OS_SDK&#xff0c;将NON-OS_SDK中的1_UART文件夹解压到工作目录即可 我这里解压到了桌面&#xff0c…

模拟框图的表示

微分方程的建立 目的&#xff1a;为建立LTI系统的数学模型&#xff0c;需要列写微分方程式。 以RLC电路为例&#xff1a; 以Us为输入&#xff0c;Uc为输入&#xff0c;则可以得出以下微分方程式&#xff1a; 抽去物理意义后&#xff0c;得到一般的常微分线性方程&#xff1a;…

朗伯特球腔均匀光源积分球

均匀光源积分球&#xff0c;又称照度积分球或光度球、光通球&#xff0c;是光电测试中常用的一种工具。它是一个中空的球体&#xff0c;内壁涂有一层平整的漫反射材料&#xff0c;通常由金属或陶瓷制成。积分球的主要功能是收集光并将其作为散射光源或测量光源使用。 积分球的工…

【Python】Python Astar算法生成最短路径GPS轨迹

简介 最短路径问题是计算机科学中一个经典问题&#xff0c;它涉及找到图中两点之间距离最短的路徑。在实际应用中&#xff0c;最短路径算法用于解决广泛的问题&#xff0c;例如导航、物流和网络优化。 步骤 1&#xff1a;加载道路网络数据 要计算最短路径&#xff0c;我们需…

脾胃,胃肠中医笔记

目录 脾胃的功能思伤脾&#xff0c;脑力工作者过度思考会伤脾胃焦虑会导致脾胃受伤按摩肚子顺时针还是逆时针&#xff0c;顺时针促消化/逆时针促排便脾胃生病症状舌苔腹胀、滞气的原因为什么大便稀&#xff1f;湿气重的原因及解决方案自测湿气重的方法 治疗脾胃药物总结补中益气…

Windows C++ 实现远程虚拟打印机(远程共享打印机)

编译错误已经修改完后的工程修改后的下载地址 https://download.csdn.net/download/2403_83063732/88928550 1、下载clawpdf&#xff08;0.8.7版本&#xff09; https://github.com/clawsoftware/clawPDF 2、打开clawpdf工程开始编译C#工程&#xff0c;出现如下错误&#xf…

Hadoop生态选择(一)

一、项目框架 1.1技术选型 技术选型主要考虑因素:维护成本、总成本预算、数据量大小、业务需求、行业内经验、技术成熟度。 数据采集传输:Flume&#xff0c;Kafka&#xff0c;DataX&#xff0c;Maxwell&#xff0c;Sqoop&#xff0c;Logstash数据存储:MySQL&#xff0c;HDFS…

【linux】04 :linix实用操作

1.常用快捷键 ctrlc表示强制停止。linux某些程序的运行&#xff0c;如果想强制停止&#xff0c;可以使用&#xff1b;命令输入错误&#xff0c;也可以通过ctrlc,退出当前输入&#xff0c;重新输入。 ctrld表示退出登录&#xff0c;比如退出root以回到普通用户&#xff0c;或者…