视频链接:韩水平老师的Java数据结构与算法——8皇后问题

八皇、N皇后后问题

八皇后问题介绍:

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于 1848 年提出:在 8×8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行、 同一列或同一斜线上,问有多少种摆法(92)。

算法思路分析:

  • 第一个皇后先放第一行第一列
  • 第二个皇后放在第二行第一列、然后判断是否 OK, 如果不 OK,继续放在第二列、第三列、依次把所有列都 放完,找到一个合适
  • 继续第三个皇后,还是第一列、第二列……直到第 8 个皇后也能放在一个不冲突的位置,算是找到了一个正确 解
  • 当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解, 全部得到
  • 然后回头继续第一个皇后放第二列,后面继续循环执行 1,2,3,4 的步骤
  • 示意图:

  • 说明:

理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法,用一个一维数组即可解决问题。arr[8] = {0 , 4, 7, 5, 2, 6, 1, 3} //对应 arr 下标 表示第几行,即第几个皇后,arr[i] = val, val 表示第 i+1 个皇后,放在第 i+1 行的第 val+1 列。

韩老师的代码

public class Queue8 {public static void main(String[] args) {// 测试一把 , 8皇后是否正确Queue8 queue8 = new Queue8();queue8.check(0);System.out.printf("一共有%d解法", count);System.out.println();System.out.printf("一共判断冲突的次数%d次", judgeCount); // 1.5w}/*** 说明:理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法,用一个一维数组即可解决问题. * arr[8] = {0 , 4, 7, 5, 2, 6, 1, 3}* 对应arr 下标 表示第几行,即第几个皇后, arr[i] = val , val 表示第i+1个皇后,放在第i+1行的第val+1列*/// 定义一个max表示共有多少个皇后int max = 8;// 8个皇后摆放在8*8棋盘// 定义数组array, 保存皇后放置位置的结果,比如 arr = {0 , 4, 7, 5, 2, 6, 1, 3}int[] array = new int[max];static int count = 0;// 记录共有多少中摆放方式static int judgeCount = 0;// 记录判断了多少次/*** 编写一个方法,放置第n个皇后 特别注意: check 是 每一次递归时, 进入到check中都有 for(int i = 0; i < max;i++)* 因此会有回溯* * @param n*/private void check(int n) {if (n == max) {// n = 8: 第n+1=9个皇后, 说明前8个皇后就已经放好print(); // 输出该情况的摆法return;// 结束}// 依次放入皇后,并判断是否冲突for (int i = 0; i < max; i++) {// 先把当前这个皇后 n , 放到该行的第(i+1)列array[n] = i;// 判断当放置第n个皇后到i列时,是否冲突if (judge(n)) { // 不冲突// 若不冲突,就接着放n+1个皇后,即开始递归check(n + 1); //}// 如果冲突,就继续执行 array[n] = i; 即将第n个皇后,放置在本行得 后移的一个位置}}/*** 判断当我们放置第n个皇后, 就去检测该皇后是否和前面已经摆放的皇后冲突* * @param n 表示第n个皇后* @return*/private boolean judge(int n) {judgeCount++;for (int i = 0; i < n; i++) {// 说明// 1. array[i] == array[n] 表示判断 第n个皇后是否和前面的n-1个皇后在同一列// 2. Math.abs(n-i) == Math.abs(array[n] - array[i]) 表示判断第n个皇后是否和第i皇后是否在同一斜线// n = 1 放置第 2列:1 <---> n = 1 array[1] = 1// Math.abs(1-0) == 1 同理 Math.abs(array[n] - array[i]) = Math.abs(1-0) = 1// 3. 判断是否在同一行, 没有必要,因为 n 每次都在递增if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) {return false;}}return true;}// 写一个方法,可以将皇后摆放的位置输出private void print() {count++;for (int i = 0; i < array.length; i++) {System.out.print(array[i] + " ");}System.out.println();}
}

力扣皇后相关题目

  • 题目链接:面试题 08.12. 八皇后、51. N 皇后、52. N皇后 II

  • 解题思路:回溯法

  • 解题代码

public class Test36 {public static void main(String[] args) {// 测试max=4System.out.println(new Test36().solveNQueens(4));}public List<List<String>> solveNQueens(int max) {/*** 说明:理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法,用一个一维数组即可解决问题. * arr[8] = {0 , 4, 7, 5, 2, 6, 1, 3}* 对应arr 下标 表示第几行,即第几个皇后, arr[i] = val , val 表示第i+1个皇后,放在第i+1行的第val+1列*/// 定义一个max表示共有多少个皇后int[] array = new int[max];// max个皇后摆放在max*max棋盘// 返回的结果集// eg:4个皇后时输出 -> [[.Q.., ...Q, Q..., ..Q.], [..Q., Q..., ...Q, .Q..]]List<List<String>> res = new ArrayList<>();// 放置第0(即第1个皇后),最多放置max个皇后,一维数组array表示的二维棋盘,需要返回的结果集check(0, max, array, res);return res;}/*** 回溯法:放置第n个皇后* @param n 放置第n+1个皇后(n从0开始)* @param max 最多放置max个皇后* @param array 一维数组array表示的二维棋盘* @param res 需要返回的结果集*/private void check(int n, int max, int[] array, List<List<String>> res) {if (n == max) { // n+1个皇后已经摆放完成,说明前n个皇后就已经放好了List<String> list = print(array);// 将该情况的摆法存入List<String>res.add(list);// 将该情况的摆法存入结果集List<List<String>>return;// 结束}// 依次放入皇后,并判断是否冲突for (int i = 0; i < max; i++) {// 先把当前这个皇后 n , 放到该行的第(i+1)列array[n] = i;// 第一个皇后在第一行第一列所有情况出现后,依次放置第n列if (judge(n, array)) {// 判断当放置第n个皇后到i列时,是否冲突// 若不冲突,就接着放n+1个皇后,即开始递归check(n + 1, max, array, res);}// 如果冲突,就继续执行 array[n] = i; 即将第n个皇后,放置在本行得 后移的一个位置}}/*** 判断摆放第n个皇时,和之前的皇后是否冲突* @param n* @param array* @return*/private boolean judge(int n, int[] array) {for (int i = 0; i < n; i++) {// 说明// 1. array[i] == array[n] 表示判断 第n个皇后是否和前面的n-1个皇后在同一列// 2. Math.abs(n-i) == Math.abs(array[n] - array[i]) 表示判断第n个皇后是否和第i皇后是否在同一斜线// n = 1 放置第 2列:1 <---> n = 1 array[1] = 1// Math.abs(1-0) == 1 同理 Math.abs(array[n] - array[i]) = Math.abs(1-0) = 1// 3. 判断是否在同一行, 没有必要,因为 n 每次都在递增if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) {return false;}}return true;}/*** 将某种情况下的摆放方式存入List<String>并返回* @param array* @return*/private List<String> print(int[] array) {List<String> list = new ArrayList<String>();for (int i = 0; i < array.length; i++) {// array = [1 3 0 2]String str = "";for (int j = 0; j < array.length; j++) {if (j == array[i]) {str = str + "Q";} else {str = str + ".";}}list.add(str);}return list;}
}

Java解决八皇后问题相关推荐

  1. 遗传算法解决八皇后问题(java源码)

    本文源码下载链接:https://download.csdn.net/download/goulvjiang3176/11221063 另有贪心算法解决八皇后问题的源码下载链接:https://dow ...

  2. 回溯法在解决八皇后问题中的应用

    回溯法:有这样一类题目,它们要求在相对问题的输入规模按照指数速度增长(或者更快)的域中,找出一个具有指定特性的元素.例如:在图顶点的所有排列中求一个哈密顿回路,在背包问题的一个实例中求其中最有价值的物 ...

  3. 递归解决八皇后问题-小昝

    引言 由于大学课堂中数据结构中并没有讲一些常见的算法,只是讲的比较简单的定义.所以拿出来暑假时间去研究经典的算法.本文章是研究的八皇后问题.八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 ...

  4. Python解决八皇后问题

    Python解决八皇后问题 参考文章: (1)Python解决八皇后问题 (2)https://www.cnblogs.com/littleseven/p/5362791.html 备忘一下.

  5. 回溯算法解决八皇后_4皇后问题和使用回溯算法的解决方案

    回溯算法解决八皇后 4-皇后问题 (4 - Queen's problem) In 4- queens problem, we have 4 queens to be placed on a 4*4 ...

  6. Python:爬山法/随机重启爬山法/允许侧移的爬山法解决八皇后问题

    文章目录 1 八皇后问题 2 程序代码 2.1 程序1 2.2 程序2 2.3 程序3 2.3.1 爬山法 2.3.2 随机重启爬山法 2.3.3 允许皇后侧移的爬山法 3 评价 1 八皇后问题 有一 ...

  7. 有趣的数据结构算法12——利用递归解决八皇后问题

    有趣的数据结构算法12--利用递归解决八皇后问题 题目复述 解题思路 实现代码 GITHUB下载连接 本次教程主要讲述如何利用递归解决八皇后问题,它和汉诺塔一样让人很难过. 题目复述 据说西洋棋手都具 ...

  8. 遗传算法解决八皇后问题

    遗传算法解决八皇后问题 程序设计的概要思想 编码方案 适应度的计算 初始种群 选择算子 交叉算子 变异算子 终止策略 程序的主要函数及其作用 运行结果截图 Python源代码 程序设计的概要思想 遗传 ...

  9. 运用全排列的方法解决八皇后问题

    运用全排列的方法解决八皇后问题,可以分为两部分:全排列和八皇后,下面我将分开说明两个步骤. 首先说明八皇后: 第一步:就是把皇后按照0到8编号,然后对八个皇后进行全排列,一共有40320种排列方式. ...

  10. 用lua解决八皇后问题

        要解决八皇后问题,首先必须认识到每一行中只能有一个皇后.因此,可以用一个由8个数字组成的简单数组来表示可能的解决方案.例如,数组{3,7,2,1,8,6,5,4}表示皇后在棋盘中的位置分别是( ...

最新文章

  1. 用like语句时的C#格式化函数
  2. php 去除首位字符_php中如何去除字符串首尾字符?
  3. GitHub 重磅开源!这个 AI 项目至少价值百万!!!
  4. 新一轮全球“太空竞赛”正上演 争夺几万亿美元大蛋糕
  5. 课时3.浏览器访问网页原理(理解)
  6. centos-install-kong-cassandra
  7. mysql ndb还原数据库_ndb_restore恢复出错
  8. 拒绝假货!LVMH与普拉达、卡地亚联手推出区块链平台AURA
  9. 拓端tecdat:Python主题建模LDA模型、t-SNE 降维聚类、词云可视化文本挖掘新闻组数据集
  10. Oracle定时任务使用
  11. 医院计算机房相关制度,医院信息科机房管理制度.doc
  12. 什么是有监督学习?看这里。
  13. Oracle设置自增序列
  14. 拒绝丧偶式育儿,正确「养育男孩」
  15. 新上线APP如何推广提升排名
  16. 计算机网络CiscoPacket Tracer实验
  17. 英语语法:词法之非谓语动词--起式
  18. 如何使用linux系统自带的led驱动
  19. safari 浏览器输入框不能输入
  20. c语言expand函数,编撰expand(s1,s2)

热门文章

  1. windows启动修复_如何使用Windows启动修复工具修复启动问题
  2. c++ 去除字符串首尾的空白字符
  3. 淘宝校园笔试题鸡蛋与篮子
  4. 木子-后端-根据出生日期算出年龄
  5. 对京东云鼎的学习笔记
  6. ACM教程 - (数论)正整数分解使得乘积最大问题
  7. iov_iter结构体
  8. Entry name ‘META-INF/xxx‘ collided报错
  9. golang--channal与select
  10. help指令和man指令的区别