0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

回溯算法经典题目之N皇后

算法与数据结构 来源:吴师兄学算法 作者:算法与数据结构 2022-09-21 15:10 次阅读
提到回溯算法那肯定离不开 n 皇后这道算法题,它实在是太经典了。

所谓n 皇后问题,指的是如何将n个皇后放置在n×n的棋盘上,并且使皇后彼此之间不能相互攻击。

皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上

给你一个整数n,返回所有不同的n 皇后问题的解决方案。

每一种解法包含一个不同的n 皇后问题的棋子放置方案,该方案中'Q''.'分别代表了皇后和空位。

输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],
["..Q.","Q...","...Q",".Q.."]]
解释:4 皇后问题存在两个不同的解法。

我觉得你应该能够结合视频动画和保姆级别的代码注释把这道题目弄清楚。

classSolution{

//保存所有符合要求的解
List>res=newArrayList<>();

publicList>solveNQueens(intn){

//attack用来表示皇后的攻击范围
int[][]attack=newint[n][n];
//queen用来记录皇后的位置
char[][]queen=newchar[n][n];

//初始化二维数组queen中所有的元素为'.'
for(char[]c:queen){
Arrays.fill(c,'.');
}

//初始化二维数组attack中所有的元素为0
//0代表没有皇后能攻击得到
//1代表出于任意一个皇后的攻击范围内
for(int[]c:attack){
Arrays.fill(c,0);
}

//从棋盘的第0行第0列处理n皇后的情况
backtrack(0,n,queen,attack);

//最后,返回所有符合要求的解
returnres;
}

//很显然,每一行只能放置一个皇后,所以我们每一行每一行的来放置皇后
//k表示当前处理的行
//n表示需要放置多少个皇后,同时也代表棋盘的大小为n*n
//queen用来记录皇后的位置
//attack用来表示皇后的攻击范围
privatevoidbacktrack(intk,intn,char[][]queen,int[][]attack){

//如果发现在棋盘的最后一行放置好了皇后,那么就说明找到了一组符合要求的解
if(k==n){
//由于queen为二维字符数组,所以需要转换为字符串数组
Listlist=newArrayList<>();
//遍历二维数组queen
//取出queen的每一行字符数组c
for(char[]c:queen){
//把字符数组c中的所有字符转换为字符串的形式进行拼凑
//比如['.','Q','.','.',]
//转换为'.Q..'
//把这个字符串加入到list中
list.add(String.copyValueOf(c));
}

//list即为一组符合要求的解,把它加入到结果数组中
res.add(list);
//由于遍历完了所有的行,无需再遍历下去,所以返回
return;
}

//每一行只能放置一个皇后
//并且每一列也只能放置一个皇后
//所以在k行中,从0列到n-1列,判断皇后应该放置到哪个位置
for(inti=0;i< n ; i++){
            //如果发现attack[k][i]==0
//说明这个位置不在任何一个皇后的攻击范围内
//所以可以考虑放置皇后
if(attack[k][i]==0){

//如果在(k,i)位置放置了皇后,那么就需要考虑在k+1行应该怎么放置其它的皇后了
//由于有可能在(k,i)位置放置了皇后之后,在后续的其它行会无法再放置其它的皇后
//那么就需要回到(k,i)的状态,考虑能不能在(k,i+1)的位置放置
//为了能够回到(k,i)的状态,所以需要先记录此时的attack
//使用一个临时的二维数组,深度拷贝attack
//如果不使用深度拷贝,而是直接使用int[][]temp=c
//会导致attack发生改变是temp也会发生改变
//这样也就无法保存之前的状态了
int[][]temp=newint[n][n];

//通过两个for循环,把attack中的所有元素深度拷贝到temp
for(intl=0;l< n ; l++){
                    for(intm=0;m< n ; m++){
                        temp[l][m] = attack[l][m];
                    }
                }

                //queen用来记录皇后的位置
//那么(k,i)的位置queen[k][i]='Q'
queen[k][i]='Q';

//由于新放置了一个皇后,所以攻击范围又更多了
//所以需要更新attack数组
//新放置皇后的坐标为(k,i),同样的需要更新它的八个方向
checkQueenAttack(k,i,attack);

//如果在(k,i)位置放置了皇后,那么就需要考虑在k+1行应该怎么放置其它的皇后
//递归的调用backtrack在k+1行放置皇后
backtrack(k+1,n,queen,attack);

//递归结束后,拿走皇后,恢复attack的状态,考虑能不能在(k,i+1)的位置放置
attack=temp;

//恢复queen的状态,说明此时皇后不放置在(k,i)位置
queen[k][i]='.';
}
}


}

//坐标(x,y)为皇后所处的位置
//更新attack
privatevoidcheckQueenAttack(intx,inty,int[][]attack){

//对于每一个坐标(x,y)来说,都有上、下、左、右、左上、左下、右上、右下八个方向
//【左上】的坐标为(x-1,y-1)
//【上】的坐标为(x-1,y)
//【右上】的坐标为(x+1,y+1)
//【左】的坐标为(x,y+1)
//【右】的坐标为(x,y-1)
//【左下】的坐标为(x+1,y-1)
//【下】的坐标为(x+1,y)
//【右下】的坐标为(x+1,y+1)
//通过两个一维数组可以表示这八个方向
//dx表示x的方向
intdx[]={-1,-1,-1,0,0,1,1,1};
//dy表示y的方向
intdy[]={-1,0,1,-1,1,-1,0,1};

//皇后所处的坐标肯定是皇后能攻击的位置,设置为1
attack[x][y]=1;

//以坐标(x,y)为中心,去更新它八个方向的坐标
for(intj=0;j< 8;j++){
//由内向外的进行更新
for(inti=1;i< attack.length ; i++){
                //新的位置的坐标行为x+i*dx[j]
intnx=x+i*dx[j];
//新的位置的坐标列为y+i*dy[j]
intny=y+i*dy[j];

//如果新位置的坐标在n*n的棋盘范围内
if(nx>=0&&nx< attack.length && ny >=0&&ny< attack.length){
                    //那么这些位置就是在坐标为(x,y)的皇后的攻击范围内,更新为1
attack[nx][ny]=1;
}

}
}
}
}

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 代码
    +关注

    关注

    30

    文章

    4803

    浏览量

    68763
  • 回溯算法
    +关注

    关注

    0

    文章

    10

    浏览量

    6623

原文标题:回溯算法经典题目之 N 皇后

文章出处:【微信号:TheAlgorithm,微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    高薪 mcu 触控算法专家(触控按键,不要触控屏)

    触摸原理,具有触摸算法/硬件的成功设计开发和调测经验(至少熟练掌握电容触摸原理); 5、精通触摸相关安规认证的测试规范; 6、具有触摸算法大量产应用经验,面向家电应用触控算法经验优先; 7、具备一定的团队管理能力。
    发表于 12-27 14:12

    恩智浦 MCX N系列电源管理(MCX N94/54与MCX N23)

    给大家揭秘MCX N系列在电源管理方面的卓越性能。电源管理对于硬件设计的优化以及低功耗应用的实现至关重要,因此,深入了解MCX N系列的电源管理机制对于开发者而言意义非凡。同时小编也列举了一些硬件设计时的注意事项,本篇文章适用于MCX
    的头像 发表于 12-05 09:49 832次阅读
    恩智浦 MCX <b class='flag-5'>N</b>系列<b class='flag-5'>之</b>电源管理(MCX <b class='flag-5'>N</b>94/54与MCX <b class='flag-5'>N</b>23)

    经典图神经网络(GNNs)的基准分析研究

    本文简要介绍了经典图神经网络(GNNs)的基准分析研究,发表在 NeurIPS 2024。 文章回顾了经典 GNNs 模型在节点分类任务上的表现,结果发现过去 SOTA 图学习模型报告的性能优越
    的头像 发表于 11-27 09:16 201次阅读
    <b class='flag-5'>经典</b>图神经网络(GNNs)的基准分析研究

    激光雷达在SLAM算法中的应用综述

    SLAM算法运行的重要传感器。基于激光雷达的SLAM算法,对激光雷达SLAM总体框架进行介绍,详细阐述前端里程计、后端优化、回环检测、地图构建模块的作用并总结所使用的算法;按由2D到 3D,单传感器到多传感器融合的顺序,对
    的头像 发表于 11-12 10:30 836次阅读
    激光雷达在SLAM<b class='flag-5'>算法</b>中的应用综述

    dp接口的最新技术发展

    深度优先搜索(DFS)是一种基本的算法,用于遍历或搜索树或图。它从一个顶点开始,尽可能深地搜索树的分支。当搜索到最深节点时,然后回溯。DFS可以用于解决许多问题,如寻找路径、检测循环、拓扑排序等
    的头像 发表于 10-30 13:52 194次阅读

    时间复杂度为 O(n^2) 的排序算法

    作者:京东保险 王奕龙 对于小规模数据,我们可以选用时间复杂度为 O(n2) 的排序算法。因为时间复杂度并不代表实际代码的执行时间,它省去了低阶、系数和常数,仅代表的增长趋势,所以在小规模数据情况下
    的头像 发表于 10-19 16:31 1191次阅读
    时间复杂度为 O(<b class='flag-5'>n</b>^2) 的排序<b class='flag-5'>算法</b>

    RVBacktrace RISC-V极简栈回溯组件

    RVBacktrace组件简介一个极简的RISC-V栈回溯组件。功能在需要的地方调用组件提供的唯一API,开始当前环境的栈回溯支持输出addr2line需要的命令,使用addr2line进行栈回溯支持结合反汇编,栈
    的头像 发表于 09-15 08:12 414次阅读
    RVBacktrace RISC-V极简栈<b class='flag-5'>回溯</b>组件

    回溯英特尔在跨越半个世纪的发展历程

    我们以英特尔三位风云人物的三句名言为线索,回溯英特尔在跨越半个世纪的发展历程中,如何利用芯片技术的力量,影响信息时代,开启未来之门。
    的头像 发表于 08-16 14:58 660次阅读

    机器学习的经典算法与应用

    关于数据机器学习就是喂入算法和数据,让算法从数据中寻找一种相应的关系。Iris鸢尾花数据集是一个经典数据集,在统计学习和机器学习领域都经常被用作示例。数据集内包含3类共150条记录,每类各50个数
    的头像 发表于 06-27 08:27 1684次阅读
    机器学习的<b class='flag-5'>经典</b><b class='flag-5'>算法</b>与应用

    什么是经典蓝牙模块?

      什么是经典蓝牙模块? 前面我们已经就蓝牙模块的概念做了了解,随着时间的推移,产品越来越智能,需要的蓝牙模块也就越来越广泛,本篇文章我们就一起了解下什么是经典蓝牙模块。 经典蓝牙模块(BT)泛指
    的头像 发表于 05-24 14:52 547次阅读
    什么是<b class='flag-5'>经典</b>蓝牙模块?

    蓝牙模块选经典蓝牙还是低功耗蓝牙?

      经典蓝牙(classic Bluetooth)和低功耗蓝牙(Bluetooth low energy,简称BLE或者LE),两者有什么区别?为什么他们都叫“蓝牙”?Bluetooth low
    的头像 发表于 05-23 17:57 1325次阅读
    蓝牙模块选<b class='flag-5'>经典</b>蓝牙还是低功耗蓝牙?

    求助,关于STM32上开发函数调用堆栈回溯的问题求解

    1、stm32f1系列 2、上了FreeRTOS 3、想开发函数调用回溯功能 在编译选项中增加了--use_frame_pointer,编程一个正常的程序(之前一直run的),测试发现,程序启动即crash,请问有没有高手之前遇到过?
    发表于 05-10 07:32

    C语言实现经典排序算法概览

    冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。
    的头像 发表于 02-25 12:27 462次阅读
    C语言实现<b class='flag-5'>经典</b>排序<b class='flag-5'>算法</b>概览

    TCP协议技术拥塞控制算法

    拥塞控制是在网络层和传输层进行的功能。在网络层,拥塞控制可以通过路由算法来控制数据包在网络中的传输,以降低网络拥塞的发生。
    的头像 发表于 02-03 17:06 2305次阅读
    TCP协议技术<b class='flag-5'>之</b>拥塞控制<b class='flag-5'>算法</b>

    verilog的135个经典实例

    verilog的135个经典实例
    发表于 02-02 10:17 14次下载