八皇后问题
问题描述
八皇后问题是回溯算法的典型案例。问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
此处贴上一种解法
问题思路
我是跟着尚硅谷的韩顺平老师的视频学习的,韩老师使用的方法是使用一个一维数组来存储单个解法,有八个皇后,所以使用一个长度为八的一维int数组来存储解法,利用数组的下标来代替行数,数组中的元素代替列数,最后只需要将数组打印,就可以得到一组答案
这个方法的好处是可以天然的过滤掉算行数的相同,只用将精力留在是否同列和同一斜线上
由于使用了数组中的元素来代替列数,所以插入元素时,只要比较和数组中之前的元素是否相同,便可以判断是否同列,十分简单,如此一来,我们剩下的问题就只有如何判断和之前的棋子在同一斜线上
如何判断两点是否在同一斜线,十分简单,这里打个比方有两个点(x, y)和(x + v, y + v),我们可以很容易的看出这两个点在同一条斜线上,这里可以用两点之间,行差=列差来判断是否在同一直线,或者可以算这两点直线的斜率,k = 1,是一条斜率为45°的直线,也就是题目描述中需要的斜线
然后具体的解题的话,就相当于将8X8的棋盘,
- 先在第一行第一列放一枚棋子
- 然后在第二行找一个可以放的位置,再在第三行找可以放的位置,以此类推,直到放到第八行得到一种解法
- 然后再逆推回来,将第八行的棋子拿走,修改第七行的棋子,看看第八行是否有别的解法,再修改第六行查看第七和第八是否有别的解法,以此类推,直到第一行
- 当换到第一行时,将第一行的棋子从第一列换到第二列,再执行2, 3两步,直到第一行的棋子放到第八列,得到全部的结果,程序终止
代码部分
package recursion;
/**
* @program: DataStructures
* @description: 八皇后问题
* @author: wind
* @create: 2020-09-12 19:37
*/
public class Queue8 {
private int max = 8;
private int[] arr = new int[max];
public static void main(String[] args) {
Queue8 queue8 = new Queue8();
queue8.check(0);
}
/**
* @Description: 此处用来判断程序是否结束和递归放置棋子
* @Param: [n 表示第n + 1颗棋子, 所以main函数中check(0)表示的是放置第一颗棋子]
* @return: void
* @Author: wind
* @Date: 2020/9/12/20:45
*/
private void check(int n