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

news2024/11/28 22:48:32

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;
    }
}

总结

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

19.8 Boost Asio 异或加密传输

异或加密是一种对称加密算法&#xff0c;通常用于加密二进制数据。异或操作的本质是对两个二进制数字进行比较&#xff0c;如果它们相同则返回0&#xff0c;如果不同则返回1。异或加密使用一把密钥将明文与密文进行异或运算&#xff0c;从而产生密文。同时&#xff0c;使用相同…

大厂面试题-MySQL中的RR隔离级别,到底有没有解决幻读问题?

就MySQL中的RR(Repeatable Reads)事务隔离级别&#xff0c;到底有没有解决幻读问题发起了激烈的讨论。 一部分人说有&#xff0c;一部分人说没有。 结论&#xff0c;MySQL中的RR事务隔离级别&#xff0c;在特定的情况下会出现幻读的问题。 所谓的幻读&#xff0c;表示在同一…

git拉取项目所有分支

1、执行git clone &#xff0c;随便拉取一个分支 2、进入成功拉取去的分支生成的文件夹中&#xff0c;执行下面的命令即可完成拉拉取&#xff0c;如下图所示 for branch in git branch -a | grep remotes | grep -v HEAD | grep -v master ; dogit branch --track ${branch#r…

【JVM】类加载器 Bootstrap、Extension、Application、User Define

以下环境为 jdk1.8 两大类 分类成员语言继承关系引导类加载器bootstrap 引导类加载器C/C无自定义类加载器extension 拓展类加载器、application 系统/应用类加载器、user define 用户自定义类加载器Java继承于 java.lang.ClassLoader 四小类 Bootstrap 引导类加载器 负责加…

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…

如何修改NX二次开发菜单到NX自带的标签页

最近一个项目需求&#xff0c;客户希望NX二次开发自定义的菜单能够集成在NX原来的标签页面上&#xff0c;但是我们以前从来没有这么做过&#xff0c;经过一番探索&#xff0c;后来解决了问题。 默认菜单在自定义页面&#xff0c;如下图所示&#xff1a; 但是我们希望这两个按钮…

TCP/IP卷一详解第二章Internet地址结构概要

在这一章中介绍了Internet中使用的网络层地址&#xff08;也就是IP地址&#xff09;&#xff0c;还有如何为Internet中的设备分配地址&#xff0c;以及各种类型的地址等等…… 一、IP地址的表示 为大家所常见的有IPV4地址和IPV6地址&#xff0c;但在IPV4地址中&#xff0c;通…

Docker安装ewomail

ewomail相关链接 官网官方安装文档gitee 开始安装 快速安装 wget -c https://down.ewomail.com/install-03.sh && sh install-03.sh 域名docker安装 创建docker容器 docker run -idt \-p 25:25 \-p 110:110 \-p 143:143 \-p 465:465 \-p 587:587 \-p 993:993 \-…

基于IGT-DSER智能网关实现GE的PAC/PLC与罗克韦尔(AB)的PLC之间通讯

工业自动化领域的IGT-DSER智能网关模块支持GE、西门子、三菱、欧姆龙、AB等各种品牌的PLC之间通讯(相关资料下载)&#xff0c;同时也支持PLC与Modbus协议的工业机器人、智能仪表等设备通讯。网关有多个网口、串口&#xff0c;也可选择WIFI无线通讯。无需编程开发&#xff0c;只…

【Unity细节】如何让组件失活而不是物体失活

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 &#x1f636;‍&#x1f32b;️收录于专栏&#xff1a;unity细节和bug &#x1f636;‍&#x1f32b;️优质专栏 ⭐【…

Linux设置N天未登录强制冻结

1、创建普通用户 2、90天未登录强制冻结 chage -E $(date -d "90 days" %Y-%m-%d) 用户名 3.更改系统日期 sudo date -s "2024-02-07 20:18:00" 4.过期未登录,提示如下 5.账号解冻 chage -E -1 用户名

AI 为先的时代,企业如何深度用云?

「又一年云栖&#xff0c;SOFAStack 走向云原生深处。」 SOFAStack 5.0 与蚂蚁集团代码大模型 CodeFuse 全面融合&#xff0c;涵盖设计、研发、测试、运维等领域&#xff0c;提供从领域建模到智能运维的端到端 Copilot 产品解决方案&#xff0c;为企业打造新一代 AI 云原生 Paa…

网络层+数据链路层+物理层

一)网络层协议: 一)IP协议报头介绍: 咱们的IP协议能够在两点之间规划处一条合适的路径&#xff0c;什么叫做合适&#xff1f;那就得看咱们的TOS是怎么进行选的&#xff0c;比如说选择最大吞吐量&#xff0c;咱们就需要进行选择一个最大的带宽路径&#xff1b; 16位总长度:IP数据…

grpc 重试机制

1.通过配置retryPolicy的方式 这也是grpc官方库里的示例代码&#xff0c;其他讲retry重试的基本也都是参照这种方法。但是本地配置之后没生效。换用下边第二种方式之后问题解决 https://github.com/grpc/grpc-go/blob/be1d1c10a930/examples/features/retry/client/main.go …

景联文科技加入中国人工智能产业发展联盟(AIIA),与行业各方共促AI产业发展

近日&#xff0c;景联文科技加入中国人工智能产业发展联盟&#xff08;AIIA&#xff09;&#xff0c;与行业各方共同挖掘人工智能数据的更多价值&#xff0c;破解中国人工智能AI数据短缺难题。 中国人工智能产业发展联盟&#xff08;简称AIIA&#xff09;是在国家发改委、科技部…

this.$message提示内容添加换行

0 效果 1 代码 let msgArr [只允许上传doc/docx/xls/xlsx/pdf/png/jpg/bmp/ppt/pptx/rar/zip格式文件,且单个文件大小不能超过20MB,已过滤无效的文件] let msg msgArr.join(<br/>) this.$message({dangerouslyUseHTMLString: true,message: msg,type: warning })

django 批量 serializers listserializers

Django drf 序列化器 序列化器 扩展serializers的有用性是我们想要解决的问题。但是&#xff0c;这不是一个微不足道的问题&#xff0c;而是需要一些严肃的设计工作。— Russell Keith-Magee, Django用户组 序列化器允许把像查询集和模型实例这样的复杂数据转换为可以轻松渲染…

电力输送、材料和互连领域即将发生巨大变化

在设备互连方面&#xff0c;铜无可匹敌。其低电阻率和高可靠性为业界提供了出色的片上互连和芯片间连线服务。但在逻辑芯片中&#xff0c;随着互连堆栈上升到14级范围&#xff0c;并且阻容(RC)延迟在总延迟中所占的比例越来越大&#xff0c;晶圆厂正在寻求替代金属来维持性能。…

LeetCode_多源 BFS_中等_2258.逃离火灾

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给你一个下标从 0 开始大小为 m x n 的二维整数数组 grid &#xff0c;它表示一个网格图。每个格子为下面 3 个值之一&#xff1a; 0 表示草地。1 表示着火的格子。2 表示一座墙&#xff0c;你跟火都不能通过…

使用ffmpeg 压缩视频

我有一批1080p的视频,在网上播放占用空间太大,需要进行压缩以后再上传,下面是记录一下ffmpeg命令的使用情况 原视频大小:288mb --压缩加修改分辨率 640p ffmpeg -y -i C4995.mp4 -vcodec libx264 -crf 18 -s vga C4995\C4995_2.MP4 -y: 强制覆盖 -i :输入文件 -vcodec lib…