Java——N皇后问题

news2024/11/20 8:30:36

题目链接

leetcode在线oj题——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

解题思路

使用深度搜索的方法,按照先行后列的顺序,查看每一个位置是否满足条件

先从第一行第一列开始,使这个位置占一个皇后,显然第一行和第一列,与其所在斜线都无法再放皇后了
在这里插入图片描述
然后按照顺序将第二个皇后放在第二行第三列
显然这种放法只能支持三个皇后
在这里插入图片描述
那么回退到上一个状态(第一个皇后在第一行第一列),按照顺序将第二个皇后放在第二行第四列
在这里插入图片描述
显然这种放法也是只能放三个,那么再次回退到上一个状态,按照顺序将第二个皇后放在第三行第二个(这时和放在第二行第三列是对称的,因此结果一致),显然也只能放四个皇后,状态回溯到上一个状态

再将第二个皇后放在第三行第四列,显然这种情况也是只能最多放三个
在这里插入图片描述
其他两个位置也和上面的位置是对称的,因此将第一个皇后放在第一行第一列的情况是没有结果的,状态回溯到没有放皇后的状态

按照顺序,我们将第一个皇后放在第一行第二位
在这里插入图片描述
再按照顺序将第二个皇后放在第二行第四列
在这里插入图片描述
按照顺序将第三个皇后放在第三行第一列上,可以发现这种情况可以放到第四个皇后,状态再次回溯到第一个状态(第一个皇后放在第一行第二列上)
在这里插入图片描述
按照顺序,将皇后放在第三行第一列,可以发现最终产生的结果和上一次的结果一样,因此状态再次退回到没有一个皇后的状态

按照顺序,将第一个皇后放在第一行第三列上
在这里插入图片描述
然后按照顺序,将第二个皇后放在第二行第一列上
在这里插入图片描述
按照顺序,第三个皇后放在第三行第四列上,可以发现最终也可以得到最终的结果
在这里插入图片描述
事实上,把第一个皇后放在第一行第三列上和放在第一行第二列上是对称的情况,因此得到的结果也是对称的

而将第一个皇后放在第一行第四列上和放在第一行第一列上是对称的情况,因此也得不到最后的结果

按照上面的思想,可以写出下面的代码

代码

class Solution {
    static class Pair{
        public int x;
        public int y;

        public Pair(int x, int y){
            this.x = x;
            this.y = y;
        }
    }

    static void DFS(List<List<Pair>> result, List<Pair> curRet,
                int curRow, int n){
        //每一行都有元素,当前结果是可行的
        if(curRow == n){
            result.add(new ArrayList<>(curRet));
            return;
        }
        //遍历每一列
        for (int i = 0; i < n; i++) {
            if(isValidPos(curRet, curRow, i)){
                curRet.add(new Pair(curRow, i));
                //处理下一行
                DFS(result, curRet, curRow + 1, n);
                //回溯
                curRet.remove(curRet.size() - 1);
            }
        }
    }

    /**
     * 判断当前位置是否有效
     * @param curRet
     * @param row
     * @param col
     * @return
     */
    private static boolean isValidPos(List<Pair> curRet, int row, int col) {
        //查看每一个已经存储的点与该点是否有冲突
        for (int i = 0; i < curRet.size(); i++) {
            Pair pair = curRet.get(i);
            if(pair.y == col || pair.x + pair.y == row + col ||
                pair.x - pair.y == row - col){
                return false;
            }
        }
        return true;
    }

    private static List<List<String>> transResult(List<List<Pair>> result, int n){
        List<List<String>> finalResult = new ArrayList<>();
        for (int i = 0; i < result.size(); i++) {
            //一种方案
            List<Pair> curRet = result.get(i);
            List<StringBuffer> stringList = new ArrayList<>();

            //先将所有位置都设置为.
            for (int j = 0; j < n; j++) {
                StringBuffer stringBuffer = new StringBuffer();
                for (int k = 0; k < n; k++) {
                    stringBuffer.append(".");
                }
                stringList.add(stringBuffer);
            }

            for (int j = 0; j < curRet.size(); j++) {
                //一种方案中的位置
                Pair pair = curRet.get(j);
                //再将对应位置设置为Q
                stringList.get(pair.x).setCharAt(pair.y, 'Q');
            }

            //重新创建一个ret,存储StringList中StringBuffer.toString后的字符串
            List<String> ret = new ArrayList<>();
            for (int j = 0; j < stringList.size(); j++) {
                ret.add(stringList.get(j).toString());
            }
            finalResult.add(ret);
        }
        return finalResult;
    }

    public static List<List<String>> solveNQueens(int n) {
        List<List<Pair>> result = new ArrayList<>();
        List<Pair> curRet = new ArrayList<>();
        DFS(result, curRet, 0, n);
        return transResult(result, n);
    }
}

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

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

相关文章

RocketMQ Broker消息处理流程剩余源码解析

&#x1f34a; Java学习&#xff1a;Java从入门到精通总结 &#x1f34a; 深入浅出RocketMQ设计思想&#xff1a;深入浅出RocketMQ设计思想 &#x1f34a; 绝对不一样的职场干货&#xff1a;大厂最佳实践经验指南 &#x1f4c6; 最近更新&#xff1a;2023年3月4日 &#x1…

CCNP350-401学习笔记(补充题目1-100)

1、wireless client to roam --->> wireless client 2、Cisco aWIPS policies on the WLC 3、 import json -->> while true -->>except -->> File open -->>File.close() -->> File.open() 4、 login console group radius 5、undesir…

大数据框架之Hadoop:MapReduce(七)MapReduce扩展案例

一、倒排索引案例&#xff08;多job串联&#xff09; 1、需求 有大量的文本&#xff08;文档、网页&#xff09;&#xff0c;需要建立搜索索引&#xff0c;如图4-31所示。 &#xff08;1&#xff09;数据输入 &#xff08;2&#xff09;期望输出数据 atguigu c.txt–>2…

VS2022+Qt5.14.2成功编译MITK2022.10

目录 一 编译结果 二 编译问题解决 三 参考链接 一 编译结果 二 编译问题解决 error C2220错误 1> mitkSlicedGeometry3D.cpp 1>D:\MITK\src\MITK-2022.10\Modules\Core\src\DataManagement\mitkSlicedGeometry3D.cpp(1,1): error C2220: 以下警告被视为错误 [D:\MI…

能代替try catch处理异常的优雅方式

前言软件开发过程中&#xff0c;不可避免的是需要处理各种异常&#xff0c;就我自己来说&#xff0c;至少有一半以上的时间都是在处理各种异常情况&#xff0c;所以代码中就会出现大量的try {…} catch {…} finally {…} 代码块&#xff0c;不仅有大量的冗余代码&#xff0c;而…

【办公类-19-03】办公中的思考——Python批量统一文件名的序号(保教主任整理打印文件)

背景需求&#xff1a;为迎接督导检查&#xff0c;保教主任从各条线收集文本资料。并在每个文件名称前手动编号。但是她嘀咕道&#xff1a;”为什么两套资料放在一个文件里就不是按照数字序号排序&#xff1f;&#xff0c;有的是1X-&#xff0c;有的是40X&#xff0c;看起来很乱…

20230304 CF855 div3 vp

Dashboard - Codeforces Round 855 (Div. 3) - Codeforces呃呃&#xff0c;评价是&#xff0c;毫无进步呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训…

有关平方或高次方的公式整理一元高次方程的求解

Part.I Introduction 这篇博文记录一下数学中常用的有关平方或高次方的一些公式。 Chap.I 一些结论 下面一部分汇总了一些重要的结论 完全平方公式&#xff1a;(ab)2a22abb2(ab)^2a^22abb^2(ab)2a22abb2平方差公式&#xff1a;a2−b2(ab)(a−b)a^2-b^2(ab)(a-b)a2−b2(ab)(…

Spring——Bean管理-注解方式进行属性注入

Spring针对Bean管理中创建对象提供的注解有哪些&#xff1f;Component&#xff1a;普通Service&#xff1a;业务逻辑层Controller&#xff1a;controller层Repository&#xff1a;dao层用注解的方式是为什么&#xff1f;简化xml方式开发&#xff0c;只需要注解就可以完成在配置…

【Redis场景5】集群秒杀优化-分布式锁

集群环境下的秒杀问题 前序 【Redis场景1】用户登录注册 【Redis场景2】缓存更新策略(双写一致) 【Redis场景3】缓存穿透、击穿问题 【Redis场景拓展】秒杀问题-全局唯一ID生成策略 【Redis场景4】单机环境下秒杀问题 在单机环境下的并发问题&#xff0c;我们可以使用相关…

39. 实战:基于api接口实现视频解析播放(32接口,窗口化操作,可导出exe,附源码)

目录 前言 目的 思路 代码实现 需要导入的模块 1. 导入解析网站列表&#xff0c;实现解析过程 2. 设计UI界面 3. 设置窗口居中和循环执行 4. 注意事项 完整源码 运行效果 总结 前言 本节将类似34. 实战&#xff1a;基于某api实现歌曲检索与下载&#xff08;附完整…

SpringCloud:Nacos的安装(Windows,Linux)

目录 一、认识和安装Nacos 1、下载 2、点击进入Github&#xff0c;进入Releases 3、点击Tags 4、解压&#xff08;Windows版&#xff09; 5、端口配置 6、启动 7、访问 二、Linux系统安装Nacos 1、打开虚拟机&#xff0c;使用xshell连接虚拟机&#xff0c;Nacos依赖于…

JVM内置锁synchronized关键字详解

目录 JVM内置锁synchronized关键字详解 设计同步器的意义 如何解决线程并发安全问题&#xff1f; synchronized原理详解 synchronized底层原理 synchronized在jdk1.6前后的变化【重点】 jdk小于1.6时 jdk>1.6时 轻量级锁何时升级为重量级锁&#xff1f;&#xff1f;…

【ROS学习笔记10】ROS中配置自定义Cpp头文件和导入自定义Python库

【ROS学习笔记10】ROS中配置自定义Cpp头文件和导入自定义Python库 文章目录【ROS学习笔记10】ROS中配置自定义Cpp头文件和导入自定义Python库一、ROS中的头文件和源文件1.1 自定义头文件调用1.2 自定义源文件调用二、Python模块的导入Reference写在前面&#xff0c;本系列笔记参…

springBoot 启动指定配置文件环境多种方案

springBoot 启动指定配置文件环境理论上是有多种方案的&#xff0c;一般都是结合我们的实际业务选择不同的方案&#xff0c;比如&#xff0c;有pom.xml文件指定、maven命令行指定、配置文件指定、启动jar包时指定等方案&#xff0c;今天我们一一分享一下&#xff0c;以供参考&a…

Java知识复习(十二)Docker

1、容器 一句话概括容器&#xff1a;容器就是将软件打包成标准化单元&#xff0c;以用于开发、交付和部署容器镜像是轻量的、可执行的独立软件包 &#xff0c;包含软件运行所需的所有内容&#xff1a;代码、运行时环境、系统工具、系统库和设置。容器化软件适用于基于 Linux 和…

Redis学习(一):NoSQL概述

为什么要使用Nosql 现在是大数据时代&#xff0c;过大的数据一般的数据库无法进行分析处理了。 单机MySQL的年代 90年代&#xff0c;一个基本的网站访问量一般不会太大&#xff0c;单个数据库完全足够&#xff01; 那个时候&#xff0c;更多的去使用静态网站&#xff0c;服务器…

TD算法超详细解释,一篇文章看透彻!

【已解决】TD算法超详细解释和实现&#xff08;Sarsa&#xff0c;n-step Sarsa&#xff0c;Q-learning&#xff09;一篇文章看透彻&#xff01; 郑重声明&#xff1a;本系列内容来源 赵世钰(Shiyu Zhao)教授的强化学习数学原理系列&#xff0c;本推文出于非商业目的分享个人学习…

DockerFile创建及案例

DockerFile dockerfile是用来构建docker镜像的文件&#xff0c;命令脚本参数脚本&#xff01; 构建步骤 编写一个dockerfile文件docker build 构建成为一个对象docker run 运行镜像docker push 发布镜像&#xff08;DockerHub、阿里云镜像仓库&#xff09; 去官网Docker-Hub…

51单片机——串口通信,小白讲解,相互学习

通讯的基本概念 51单片机不仅可以实现串口通信&#xff0c;还可以通过IO口模拟实现多种其他通信&#xff0c;比如 SPI&#xff0c;IIC等&#xff0c;学习这些通信前&#xff0c;我们很有必要了解下通信的基本概念。通信的方式可以分为多种&#xff0c;按照数据传输方式可分为串…