力扣日记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再col
        vector<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)
    • 在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【大数据】通过 docker-compose 快速部署 MinIO 保姆级教程

文章目录 一、概述二、MinIO 与 Ceph 对比1&#xff09;架构设计对比2&#xff09;数据一致性对比3&#xff09;部署和管理对比4&#xff09;生态系统和兼容性对比 三、前期准备1&#xff09;部署 docker2&#xff09;部署 docker-compose 四、创建网络五、MinIO 编排部署1&…

插件WebApiClient.JIT的使用方法

我们在项目开发过程中&#xff0c;经常需要调用第三方接口&#xff0c;使用httpclient需要写一堆代码&#xff0c;使用插件WebApiClient.JIT可以简化很多代码量&#xff0c;接下来介绍一下WebApiClient.JIT的使用方式。 添加引用&#xff0c;打开NuGet&#xff0c;查询插件&am…

vue3+element plus 实现百度地图显示路径

添加依赖 <!-- index.html --><script type"text/javascript" src"//api.map.baidu.com/getscript?v3.0&akyI6kBeC9G4LntEWXklE2iNHwRUrmFEQc"></script><script type"text/javascript" src"//api.map.baidu.co…

【python基础学习11课_异常机制】

一、异常 1、异常的定义 异常&#xff1a;程序无法继续执行异常会中断程序执行异常处理&#xff0c;是为了不中断程序执行。而不是避免错误。有些代码是报错就是要暴露出来有了异常机制&#xff0c;错误的代码报错后抛出异常&#xff0c;代码从上到下&#xff0c;报错代码后面…

【PCIe】初识PCIe

&#x1f525;博客主页&#xff1a;[PannLZ] &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 文章目录 PCIe简介PCIe速度 PCIe简介 计算机内部有很多电子元器件&#xff0c;他们之间会有数据沟通和传输的需求。如果A元件想给B元件传输数据&am…

Axure RP 10:让原型设计更快、更直观、更智能 mac版

Axure RP 10是一款强大的原型设计工具&#xff0c;它能够帮助设计师快速创建高保真、交互式的原型&#xff0c;从而更好地展示和测试设计方案。这款软件凭借其直观易用的界面和丰富的功能&#xff0c;已经成为了许多设计师的首 选工具。 Axure RP 10 for Mac版软件获取 首先&a…

使用Matlab计算IGRAv2探空站的Tm和PWV

1. 探空站IGRAv2数据 探空站的Tm常作为真值&#xff0c;去检验Tm线性公式或者ERA5 Tm等的精度 。 探空站PWV常作为真值&#xff0c;去检验GNSS PWV等的精度 2. Tm 的计算方法 Tm 的计算方法有两种在前面的文章有讲&#xff0c;这里用 使用水汽压和温度计算Tm。 ei和 Ti 表示…

Day15:技术架构、Maven、Spring Initializer、Spring全家桶、Spring IoC

侧重于服务端&#xff08;后端&#xff09;&#xff0c;不在意前端&#xff0c;了解一些前端即可&#xff09; 技术架构 &#xff08;把Spring设计的更简单好用了就是Spring Boot&#xff09; 开发环境&#xff08;Maven&#xff09; Maven maven通过brew安装的目录为&#x…

学习网络安全越早知道越好的事

网络安全专业最应该知道的血泪建议&#xff0c;希望大一就有人告诉你。 如果你是网络安全行业&#xff0c;那么大学四年千万不能就在宿舍打游戏度过&#xff0c; 大一你应该学习掌握基础的编程语言&#xff0c;比如Python&#xff0c;PHP&#xff0c;web前端&#xff0c;知道…

基于深度学习的交通标志检测识别系统(含UI界面、yolov8、Python代码、数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov8 yolov8主要包含以下几种创新&#xff1a;         1. 添加注意力机制&#xff08;SE、CBAM等&#xff09;         2. 修改可变形卷积&#xff08;DySnake-主干c…

[动态规划][蓝桥杯 2022 省 B] 李白打酒加强版 -- 代码注释含详解

P8786 [蓝桥杯 2022 省 B] 李白打酒加强版(洛谷) 洛谷题目链接 李白打酒很快活&#xff0c;而我打了一晚上代码才把这题弄懂&#x1f972; P8786 [蓝桥杯 2022 省 B] 李白打酒加强版(洛谷)题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示\***\*\*\*\*\***\*\*\**…

谷粒商城【成神路】-【9】——商城页面

目录 &#x1f9c8;1.项目服务部署架构 &#x1f95e;2.Thymealf &#x1f37f;3.请求接口 &#x1f32d;4.使用nginx转发 &#x1f956;5.nginx动静分离 &#x1fad3;6.优化 1.项目服务部署架构 使用nginx动静分离&#xff0c;使图片、js等静态资源和服务器请求分开…

基于51单片机的公交ic卡系统设计

目 录 摘 要 I Abstract II 引 言 1 1 总体方案设计 3 1.1 方案选择 3 1.2 硬件选择 3 1.3 系统工作原理 4 1.4 总体方案确定 5 2 系统硬件电路设计 6 2.1 主控模块电路设计 6 2.2 电源电路设计 8 2.3 显示电路模块设计 8 2.4 报警模块电路设计 10 2.5 RC522刷卡模块 10 2.6 独…

[网络安全] PKI

一、PKI 概述 名称; 公钥基础设施 (Public Key Facility) 作用: 通过加密技术和数字签名保证信息安全 组成: 公钥机密技术、数字证书、CA、RA 二、信息安全三要素 机密性&#xff1a;确保仅信息发收双方 能看懂信息 完整性&#xff1a; 确保信息发收完整&#xff0c;不被破坏 …

MUMU模拟器12连logcat的方法

大家好&#xff0c;我是阿赵。   在开发手机游戏的时候&#xff0c;在真机上会出现各种问题&#xff0c;在查询问题的时候&#xff0c;安卓手机需要用adb连接来连接手机看logcat输出分析问题。但由于连接手机比较麻烦&#xff0c;所以我都习惯在电脑用安卓模拟器来测试。   …

Chrome安装Axure插件

打开原型目录/resources/chrome&#xff0c;重命名axure-chrome-extension.crx&#xff0c;修改后缀为rar&#xff0c;axure-chrome-extension.rar 解压到axure-chrome-extension目录打开Chrome&#xff0c;更多工具->扩展程序&#xff0c;打开开发者模式&#xff0c;选择加…

Java 8

欢迎阅读这篇Java 8 教程。本教程旨在深入探讨Java 8的新特性&#xff0c;包括Lambda表达式、流API、新的日期时间API和更多内容。通过具体的示例和详细的解释&#xff0c;你将能够理解这些特性的用法&#xff0c;并将其应用到你的日常编程中。让我们开始吧。 一、默认方法和静…

KOA优化最近邻分类预测(matlab代码)

KOA-最近邻分类预测matlab代码 开普勒优化算法&#xff08;Kepler Optimization Algorithm&#xff0c;KOA&#xff09;是一种元启发式算法&#xff0c;灵感来源于开普勒的行星运动规律。该算法模拟行星在不同时间的位置和速度&#xff0c;每个行星代表一个候选解&#xff0c;…

【Python】新手入门(9):数值和序列

&#x1f40d;【Python】新手入门&#xff08;9&#xff09;&#xff1a;数值和序列 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&am…

今日份实验,剪了个头发,克隆了无数个自己,还是不断push

这个是今天用editor编辑器跑出来的数据&#xff0c;以下是用git跑出来的数据 下面是通过Xftp建立的会话。 用来跑一下以前的源代码 不过&#xff0c;noonxin.com, yuanjianchufang.com,网站好像不能访问&#xff0c;可能是域名出现问题&#xff0c;登录和注册也是存在问题的…