62、回溯-N皇后

思路:

        N皇后问题要求在一个n×n的棋盘上放置n个皇后,使得它们不能相互攻击。皇后可以攻击同一行、同一列,以及两个对角线方向上的其他皇后。解决这个问题意味着找到所有可能的棋盘配置,每个配置都符合上述条件。 

1、初始化数据结构

  • 使用一个整型数组record来记录每个皇后的位置。其中record[i] = j表示第i行的皇后位于第j列。
  • 使用一个列表list来收集所有有效的棋盘配置。

2. 递归和回溯

利用递归函数遍历棋盘的所有可能状态,对每一行尝试放置一个皇后,并通过回溯方法探索所有可能的解决方案:

  • 递归函数定义:创建一个递归函数process2(i, record, n, list),其中i代表当前行,record用于记录皇后位置,n为棋盘大小,list用于存储所有合法的棋盘配置。
  • 终止条件:当当前行i等于n时,表示所有行都已经成功放置了皇后。此时根据record数组生成一个棋盘配置,加入到解决方案列表list中。

3. 验证放置是否有效

在递归中,对于每一行的每一列,检查放置皇后是否合法:

  • 列冲突:确保没有其他皇后在同一列。
  • 对角线冲突:确保没有其他皇后在两个可能的对角线上。
    • 这可以通过检查当前尝试放置的列的索引与之前每行皇后列的索引的差的绝对值是否等于行的差的绝对值来实现。

4. 生成棋盘配置

每当找到一个有效的皇后布局后,需要将其转换为棋盘的字符串表示形式:

  • 对于record中的每个元素(表示列位置),构造一个字符串,其中'Q'表示皇后的位置,而'.'表示空位。

5. 回溯

  • 每次尝试放置一个皇后后,进入下一行继续尝试。
  • 如果发现当前行的某个列位置导致无法找到有效配置,则回溯到上一行,改变皇后的位置,然后再次尝试。
  • 通过逐行递归和回溯,可以探索棋盘的所有可能状态,直到找到所有有效的解决方案。

通过这种结合递归与回溯的方法,N皇后问题可以被系统地解决,所有可能的棋盘配置都会被找到并记录。

class Solution {
    // 主函数,用于解决n皇后问题,接收棋盘大小n,返回所有合法的棋盘配置
    public List<List<String>> solveNQueens(int n) {
        if (n < 1) {
            return new ArrayList<>(); // 如果n小于1,直接返回空列表,因为没有可行的棋盘配置
        }
        int[] record = new int[n]; // 创建数组记录每一行皇后的列位置
        List<List<String>> list = new ArrayList<>(); // 存储所有有效的棋盘配置
        process2(0, record, n, list); // 从第0行开始递归处理放置皇后
        return list; // 返回所有找到的棋盘配置
    }

    // 递归函数,用于处理从第i行开始的皇后放置
    private void process2(int i, int[] record, int n, List<List<String>> list) {
        if (i == n) { // 如果已经处理完所有行
            List<String> childList = new ArrayList<>(); // 创建一个新的列表存储当前棋盘的一种配置
            for (int index = 0; index < record.length; index++) { // 遍历每一行
                int num = record[index]; // 获取当前行皇后的列位置
                StringBuilder builder = new StringBuilder(); // 使用StringBuilder构建每一行的字符串表示
                for (int j = 0; j < n; j++) { // 遍历每一列
                    if (j == num) {
                        builder.append('Q'); // 如果当前列是皇后的位置,添加'Q'
                    } else {
                        builder.append('.'); // 否则添加'.'
                    }
                }
                childList.add(builder.toString()); // 将构建好的字符串加入到当前棋盘配置中
            }
            list.add(childList); // 将当前配置添加到解决方案列表中
        } else {
            // 尝试在当前行i放置皇后的所有可能列
            for (int j = 0; j < n; j++) {
                if (isValid(record, i, j)) { // 检查在第i行的第j列放置皇后是否有效
                    record[i] = j; // 如果有效,记录这个位置
                    process2(i + 1, record, n, list); // 递归处理下一行
                }
            }
        }
    }

    // 检查在第i行的第j列放置皇后是否会导致冲突
    public static boolean isValid(int[] record, int i, int j) {
        for (int k = 0; k < i; k++) { // 检查之前的每一行
            // 判断列冲突和对角线冲突
            if (j == record[k] || Math.abs(record[k] - j) == Math.abs(i - k)) { 
                return false; // 如果有冲突,返回false
            }
        }
        return true; // 如果没有冲突,返回true
    }
}

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

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

相关文章

Docker 入门篇(二)-- Linux 环境离线安装

引言 docker 系列文章&#xff1a; Docker 入门篇&#xff08;一&#xff09;-- 简介与安装教程&#xff08;Windows和Linux&#xff09; 一、安装环境准备 centos &#xff1a;CentOS Linux release 7.6.1810 (Core)docker 版本&#xff1a;docker-26.1.0.tgz 官网下载地址…

Linux驱动开发——(七)Linux阻塞和非阻塞IO

目录 一、阻塞和非阻塞IO简介 二、等待队列 2.1 等待队列头 2.2 等待队列项 2.3 将队列项添加/移除等待队列头 2.4 等待唤醒 2.5 等待事件 三、轮询 四、驱动代码 4.1 阻塞IO 4.2 非阻塞IO 一、阻塞和非阻塞IO简介 IO指的是Input/Output&#xff0c;也就是输入/输…

十个案例学习Flume

在上一篇文章中&#xff0c;已经知道了Flume的架构、概述、与安装&#xff0c;现在我们来用十个案例去学习flume的使用。 在使用之前&#xff0c;提供一个大致思想&#xff0c;使用Flume的过程是确定scource类型&#xff0c;channel类型和sink类型&#xff0c;编写conf文件并开…

零基础HTML教程(30)--迈入HTML5新时代

文章目录 1. 从H4时代到H5时代2. 属性值可以不用引号3. 标签使用大小写均可4. 部分属性值可以省略5. 浏览器支持情况6. 小结 1. 从H4时代到H5时代 之前讲的29篇HTML教程&#xff0c;内容基本都是H4时代就有的。 随着时代的发展&#xff0c;H4多少有点不够用&#xff0c;所以H…

Kotlin基础​​

数据类型 定义变量 var表示定义变量&#xff0c;可以自动推导变量类型&#xff0c;所以Int可以不用写。 定义常量 条件语句 if表达式可以返回值&#xff0c;该值一般写在if里的最后一行 类似switch的用法 区间 循环 a是标签&#xff0c;可以直接break到标签的位置&#xf…

【八大排序(二)】选择排序与堆排序

❣博主主页: 33的博客❣ ▶️文章专栏分类:八大排序◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多排序知识 目录 1.前言2.选择排序2.1基本思想2.2画图理解2.3单向选择排序代码实现2.4双向选择排序代码…

从零入门区块链和比特币(第一期)

欢迎来到我的区块链与比特币入门指南&#xff01;如果你对区块链和比特币感兴趣&#xff0c;但不知道从何开始&#xff0c;那么你来对地方了。本博客将为你提供一个简明扼要的介绍&#xff0c;帮助你了解这个领域的基础知识&#xff0c;并引导你进一步探索这个激动人心的领域。…

swagger xss漏洞复现

swagger xss漏洞复现 文章目录 swagger xss漏洞复现漏洞介绍影响版本实现原理漏洞复现修复建议: 漏洞介绍 Swagger UI 有一个有趣的功能&#xff0c;允许您提供 API 规范的 URL - 一个 yaml 或 json 文件&#xff0c;将被获取并显示给用户 根本原因非常简单 - 一个过时的库Dom…

预见预判|AIRIOT智慧交通管理解决方案

随着机动车保有量的逐步增加&#xff0c;城市交通压力日益增大。同时&#xff0c;新能源车辆的快速发展虽然带来了环保效益&#xff0c;但也因不限号政策而进一步加剧了道路拥堵问题。此外&#xff0c;各类赛事和重大活动的交通管制措施也时常导致交通状况复杂多变。面对这些挑…

Java 基础常见面试题整理

目录 1、java的基本数据类型有哪些&#xff1f;2、java为什么要有包装类型&#xff1f;3、String a "123" 和 String a new String("123") 区别&#xff1f;4、String、StringBuilder和StringBuffer的区别&#xff1f;5、如何理解面向对象和面向过程&…

MySQL常见问题与解决方案详述

MySQL&#xff1a;常见问题与解决方案详述 作为一款广泛使用的开源关系型数据库管理系统&#xff0c;MySQL对于初学者来说既充满吸引力又充满挑战。本文将列举初学者在使用MySQL过程中可能遇到的一些典型问题&#xff0c;并提供详细的解决方案&#xff0c;配以图片辅助说明&am…

修改后门ctime | Linux 后门系列

0x00 前情提要 在 alias 后门 &#xff5c; Linux 后门系列一文中&#xff0c;我们为了让后门完美一些&#xff0c;修改了后门文件的 atime、mtime&#xff0c;但是 ctime 一直没有办法修改&#xff0c;今天我们来把这一块补齐&#xff0c;让后门更加完美 atime -> access t…

Chrome 网络调试程序 谷歌网络调试 network

目录 1.网络面板总览2.概况了解3.Waterfall接口排队等待时间4.关注请求接口的Size,可能是占据内存溢出的接口5.过滤器一栏 fetch/xhr 什么意思6. Stalled 什么意思7.Queueing 什么意思8.Queueing和Stalled之间什么关系9.为什么会有阻塞状态10.Time列是pending 什么意思 1.网络面…

Vue入门篇:生命周期,钩子函数,工程化开发Vue(脚手架安装),组件化开发(全局注册,局部注册)

目录 1.Vue生命周期和生命周期的四个阶段2.Vue生命周期函数&#xff08;钩子函数)3.工程化开发&脚手架Vue CLI1.在powershell管理员权限下打开命令行安装脚手架&#xff1a;2.查看vue版本&#xff1a;3.创建项目架子4.运行项目 4.组件化开发&根组件1.App.vue文件&#…

解决双击PDF文件出现打印的问题【Adobe DC】

问题描述 电脑安装Adobe Acrobat DC之后&#xff0c;双击PDF文件就会出现打印&#xff0c;而无法直接打开。 右键PDF文件就会发现&#xff0c;第一栏出现的不是用Adobe打开&#xff0c;而是打印。 重装软件多次仍然无法解决。 原因 右键菜单被改写了。双击其实是执行右键菜…

计算机网络—— book

文章目录 一、概述1.1互联网的核心部分1&#xff0e;电路交换的主要特点2&#xff0e;分组交换的主要特点 1.2.计算机网络的性能1&#xff0e;速率2&#xff0e;带宽3&#xff0e;吞吐量4&#xff0e;时延5&#xff0e;利用率 1.3.计算机网络体系结构协议与划分层次具有五层协议…

Git如何配合Github使用

1.安装Git https://git-scm.com/ ##2.配置 Git 安装完成后&#xff0c;你需要设置 Git 的用户名和邮箱地址&#xff0c;这样在提交代码时就能知道是谁提交的。你可以在命令行中输入以下命令来配置&#xff1a; git config --global user.name "Your Name" git con…

JavaScript创建和填充数组的更多方法

空数组fill()方法创建并填充数组 ● 我们之前创建数组的方式都是手动去创建去一个数据&#xff0c;例如 console.log([1, 2, 3, 4, 5, 6, 7]);● 当然我们也可以使用Array对象来构造数组 console.log([1, 2, 3, 4, 5, 6, 7]); console.log(new Array(1, 2, 3, 4, 5, 6, 7));…

惊爆:Apple重启OpenAI谈判为iphone引入其技术

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

用宝塔部署一套自己的漏洞扫描OpenVAS

一、OpenVAS简单说明 OpenVAS是一个开源且功能开放的网络安全漏洞评估系统&#xff0c;它集成了多种相关工具&#xff0c;构成了一套全面的网络扫描解决方案。因此&#xff0c;OpenVAS能够免费提供给用户部署和使用。在其最新版本中&#xff0c;仅需安装一个基于浏览器/服务器架…