LeetCode算法题解(回溯、难点)|LeetCode51. N 皇后

LeetCode51. N 皇后

题目链接: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
算法分析:

首先我们创建一张字符串数组ArrayList<StringBuffer> path2来描述整张棋盘(因为后面需要对棋盘上地每个格子进行操作也即字符串中的元素,所以我们用StringBuffer来当作数组元素),然后用"."来填充棋盘上地每个格子。

然后通过递归一层一层的去遍历棋盘(path),然后放置皇后"Q";

递归结束条件:当放置到最后一层时,说明已经有一种放置方法了,将这种解法放置到结果及当中。

代码如下:

  public void backTravel(int startx) {//递归时,向下一层一层地放置皇后
        if(startx == len) {//如果最后一层也放了皇后,说明有一种解法了。
        //将path2先转化成String再,将其放到结果集
            ....
            return;
        }
}

然后在每一层当中,从左到右一次去遍历,并判断该位置是否可以放皇后,如果可以放置,将当前位置的字符修改为"Q",然后递归下一层,在回溯:

       for(int j = 0; j < len; j++) {//每一层,从左到右遍历,并判断该位置是否可以放置皇后
            if(canPut(startx, j) == true) {
               ... //如果可以放置,将当前位置地字符'.'修改成'Q';
                ...//递归,去放置下一层
                ...//回溯
            }
        }

 判断当前是否可以放置皇后的方法:

    public boolean canPut(int x, int y) {//用来判断坐标位置是否可以放上皇后
        for(int j = y; j < len; j++) {//向左搜索是否有皇后,因为还没对右边操作过所以不用遍历
            ....
            return false;
        }
        for(int i = x; i >= 0; i--) {//向上搜索是否幽皇后,因为还没对下边进行操作所以不用遍历
           .....
            return false;
        }
        for(int i = x - 1, j = y - 1; i >= 0 && j >= 0; i--, j--) {//向左上对角线遍历是否有皇后
            .....
            return false;
        }
        for(int i = x - 1, j = y + 1; i >=0 && j < len; i--, j++) {//向右上对角线遍历是否有皇后
            .....
            return false;
        }
        //如果左边,右边,左上对角线,右上对角线都没有皇后说明可以在当前位置放置皇后,返回true
        return true;
    }

完整的代码如下:

class Solution {
    List<List<String>>result = new ArrayList<>();//用来收集所有的解法
    ArrayList<StringBuffer>path = new ArrayList<>();//用来遍历每种解法,因为要对每个字符串中的字符进行修改操作,所以用StringBuffer
    int len;//矩形边长
    public boolean canPut(int x, int y) {//迎来判断坐标位置是否可以放上皇后
        for(int j = y; j < len; j++) {//向左搜索是否有皇后,因为还没对右边操作过所以不用遍历
            if(path.get(x).charAt(j) == 'Q')
            return false;
        }
        for(int i = x; i >= 0; i--) {//向上搜索是否幽皇后,因为还没对下边进行操作所以不用遍历
            if(path.get(i).charAt(y) == 'Q')
            return false;
        }
        for(int i = x - 1, j = y - 1; i >= 0 && j >= 0; i--, j--) {//向左上对角线遍历是否有皇后
            if(path.get(i).charAt(j) == 'Q')
            return false;
        }
        for(int i = x - 1, j = y + 1; i >=0 && j < len; i--, j++) {//向右上对角线遍历是否有皇后
            if(path.get(i).charAt(j) == 'Q')
            return false;
        }
        //如果左边,右边,左上对角线,右上对角线都没有皇后说明可以在当前位置放置皇后,返回true
        return true;
    }
    public void backTravel(int startx) {//递归时,向下一层一层地放置皇后
        if(startx == len) {//如果最后一层也放了皇后,说明有一种解法了。
        //将path2先转化成String再,将其放到结果集
            ArrayList<String>path2 = new ArrayList<>();
            for(StringBuffer sb : path) {
                path2.add(sb.toString());
            }
            result.add(path2);
            return;
        }
        for(int j = 0; j < len; j++) {//每一层,从左到右遍历,并判断该位置是否可以放置皇后
            if(canPut(startx, j) == true) {
                //如果可以放置,将当前位置地字符'.'修改成'Q';
                path.get(startx).setCharAt(j, 'Q');
                backTravel(startx + 1);//递归,去放置下一层
                path.get(startx).setCharAt(j, '.');//回溯
            }
        }
    }
    public List<List<String>> solveNQueens(int n) {
        len = n;
        for(int i = 0; i < n; i++) {//将path2填充上'.';
            StringBuffer sb = new StringBuffer();
            for(int j = 0; j < n; j++) 
            sb.append(".");
            path.add(sb);
        }
        backTravel(0);
        return result;
    }
}

总结

这道题的难点是如何用字符来描述棋盘,并对每个格子进行是否可以放置皇后的判断和操作。

然后是放置皇后的顺序,我们用递归从上往下一层一层去遍历,每一层当中要从左到右一个个位置判断并放置皇后(注意回溯,每一层只能放一个)。

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

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

相关文章

[PyTorch][chapter 61][强化学习-免模型学习 off-policy]

前言&#xff1a; 蒙特卡罗的学习基本流程&#xff1a; Policy Evaluation : 生成动作-状态轨迹,完成价值函数的估计。 Policy Improvement: 通过价值函数估计来优化policy。 同策略&#xff08;one-policy&#xff09;&#xff1a;产生 采样轨迹的策略 和要改…

【K8s集群离线安装-kubeadm】

1、kubeadm概述 kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。这个工具能通过两条指令快速完成一个kubernetes集群的部署。 2、环境准备 2.1 软件环境 软件版本操作系统CentOS 7Docker19.03.13K8s1.23 2.2 服务器 最小硬件配置&#xff1a;2核CPU、2G内存…

19.5 Boost Asio 传输结构体

同步模式下的结构体传输与原生套接字实现方式完全一致&#xff0c;读者需要注意的是在接收参数是应该使用socket.read_some函数读取&#xff0c;发送参数则使用socket.write_some函数实现&#xff0c;对于套接字的解析同样使用强制指针转换的方法。 服务端代码如下所示 #incl…

「Verilog学习笔记」4位数值比较器电路

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 分析 这里要注意题目的“门级描述方式”&#xff0c;所以我们只能使用基本门电路&#xff1a;&,|,!,^,^~。 具体实现思路&#xff1a;通过真值表得出Y0 Y1 Y2的逻辑表达…

Vue3使用vue-print-nb插件打印功能

插件官网地址https://www.npmjs.com/package/vue-print-nb 效果展示: 打印效果 根据不同的Vue版本安装插件 //Vue2.0版本安装方法 npm install vue-print-nb --save pnpm install vue-print-nb --save yarn add vue-print-nb//Vue3.0版本安装方法&#xff1a; npm install vue3…

优思学院|CTP和CTQ是什么?有什么区别?

CTQ 关键质量特性 CTQ是在六西格玛管理中常用的重要词汇&#xff0c;所以很多不同界别的人仕都可能听过&#xff0c;CTQ的意思是关键质量特性&#xff0c;Critical To Quality 的缩写。 六西格玛管理提倡的方法是通过客户的声音 (Voice of customer-VOC) &#xff0c;然后把它…

绝对力作:解锁string的所有关键接口,万字深度解析!

W...Y的主页 &#x1f60a; &#x1f354;前言&#xff1a; 通过博主的上篇文章&#xff0c;我相信大家已经认识了STL并且已经迫不及待想学习了&#xff0c;现在我们就走近STL的第一种类——string。 目录 为什么学习string类&#xff1f; C语言中的字符串 标准库中的str…

使用 Socks5 来劫持 HTTPS(TCP-TLS) 之旅

MITM 劫持的过程中&#xff0c;HTTP 协议并不是唯一选择。 实际在 MITM 使用过程中&#xff0c;BurpSuite 和 Yakit 提供的交互式劫持工具只能劫持 HTTP 代理的 TLS 流量&#xff1b;但是这样是不够的&#xff0c;有时候我们并不能确保 HTTP 代理一定生效&#xff0c;或者说特…

【js逆向实战】某sakura动漫视频逆向

写在前面 再写一个逆向实战&#xff0c;后面写点爬虫程序来实现一下。 网站简介与逆向目标 经典的一个视频网站&#xff0c;大多数视频网站走的是M3U8协议&#xff0c;就是一个分段传输&#xff0c;其实这里就有两个分支。 通过传统的m3u8协议&#xff0c;我们可以直接进行分…

python回文日期 并输出下一个ABABBABA型回文日期

题目&#xff1a; 输入&#xff1a; 输入包含一个八位整数N&#xff0c;表示日期 对于所有的测评用例&#xff0c;10000101 ≤N≤89991231&#xff0c;保证N是一个合法日期的8位数表示 输出&#xff1a; 输出两行&#xff0c;每行一个八位数。第一行表示下一个回文日期第二…

【论文阅读】DALL·E: Zero-Shot Text-to-Image Generation

OpenAI第一代文本生成图片模型 paper&#xff1a;https://arxiv.org/abs/2102.12092 DALLE有120亿参数&#xff0c;基于自回归transformer&#xff0c;在2.5亿 图片-文本对上训练的。实现了高质量可控的text to image&#xff0c;同时也有zero-shot的能力。 DALL-E没有使用扩…

【腾讯云 HAI域探秘】探索AI绘画之路:利用腾讯云HAI服务打造智能画家

目录 前言1 使用HAI服务作画的步骤1.1 注册腾讯云账户1.2 创建算力服务器1.3 进入模型管理界面1.4 汉化界面1.5 探索AI绘画 2 模型参数的含义和调整建议2.1 模型参数的含义和示例2.2 模型参数的调整建议 3 调整参数作画的实践和效果3.1 实践说明3.2 实践效果13.3 实践效果23.4 …

专门为Web应用程序提供安全保护的设备-WAF

互联网网站面临着多种威胁&#xff0c;包括网络钓鱼和人为的恶意攻击等。这些威胁可能会导致数据泄露、系统崩溃等严重后果。 因此&#xff0c;我们需要采取更多有效的措施来保护网站的安全。其中WAF&#xff08;Web application firewall&#xff0c;Web应用防火墙&#xff0…

网站接口测试记录

1.被测试服务器端口输入htop指令进行cpu监控 2.测试机器安装宝塔-》我的工具-》进行网站测试 访问地址&#xff1a;https://www.bt.cn/bbs/thread-52772-1-1.html

Spring Cloud智慧工地管理平台源码,智慧工地APP源码,实现对劳务人员、施工进度、工地安全、材料设备、环境监测等方面的实时监控和管理

智慧工地管理平台源码&#xff0c;智慧工地APP源码&#xff0c; 智慧工地管理平台实现对人员管理、施工进度、安全管理、材料管理、设备管理、环境监测等方面的实时监控和管理&#xff0c;提高施工效率和质量&#xff0c;降低安全风险和环境污染。智慧工地平台支持项目级、公司…

SpringCloud——负载均衡——Ribbon

负载均衡分为集中式LB(Nginx实现)和进程内LB(Ribbon)。 Ribbon简单来说就是负载均衡RestTemplate调用。 1.Ribbon在工作中分成两步 1.先选择EurekaServer&#xff0c;它优先选择在同一个区域内负载较少的EurekaServer。 2.在根据用户指定的策略&#xff0c;从服务注册的列表…

Go 什么是循环依赖

Go 中的循环依赖是指两个或多个包之间相互引用&#xff0c;形成了一个循环依赖关系。这种情况下&#xff0c;包 A 依赖包 B&#xff0c;同时包 B 也依赖包 A&#xff0c;导致两个包之间无法明确地确定编译顺序&#xff0c;从而可能引发编译错误或其他问题。循环依赖是 Go 中需要…

js实现向上、向下、向左、向右无缝滚动

向左滚动 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, ini…

ClickHouse Keeper: Coordination without the drawbacks没有缺点的分布式协作系统

ClickHouse Keeper 介绍 现代分布式系统需要一个共享和可靠的信息存储库和共识系统来协调和同步分布式操作。对于ClickHouse来说&#xff0c;ZooKeeper最初是被选中的。它的广泛使用是可靠的&#xff0c;提供了简单而强大的API&#xff0c;并提供了合理的性能。 然而&#xf…

三菱FX3U系列-定位指令

目录 一、简介 二、指令形式 1、相对定位[DRVI、DDRVI] 2、绝对定位[DRVA、DDRVA] 三、总结 一、简介 定位指令用于控制伺服电机或步进电机的位置移动。可以通过改变脉冲频率和脉冲数量来控制电机的移动速度和移动距离&#xff0c;同时还可以指定移动的方向。 二、指令形…