Money is not everything. There's MasterCard.
金钱不是万能的, 有时还须要信用卡。
大话西游之月光宝盒这部电影已经刷了N遍了。每一次看都有每一次的感悟。若是时光能够到倒流,我当初就不该该。。。 悔不当初,悔不当初。git
虽然世界上没有后悔药,可是算法界倒是有后悔药的,呢就是---回溯算法。人生不能时光倒流,呢我让个人算法时光倒流。github
八皇后问题最先是由国际象棋棋手马克斯·贝瑟尔于1848年提出的,如今都21世纪了,八皇后怎么能知足我,我决定实现一个N皇后,我想要几个皇后就要几个皇后。
算法
全部源码均已上传至github:连接数组
家家有本难念的经,一个皇后已经了不起了。这N皇后嘛,可得好好处理,不能让她们打架。能够先声明一个大小为N的一维数组,来存储个人这N位皇后。而后分红N个阶段。bash
大概思路就是这样。测试
/**
* 皇后数组
*/
private int[] queens;
/**
* n皇后
*/
private int n;
/**
* 摆法数量
*/
private int count;
/**
* 基于8皇后而衍生的N皇后
*
* @param n 皇后的数量
*/
private SolveNQueens(int n) {
queens = new int[n];
this.n = n;
count = 0;
}复制代码
虽然代码很精简,可是关键就在于这个递归很差理解。循环里套递归,很巧妙。须要一步一步跟一下就知道了。ui
一维数组存储的值是皇后的位置(0,n-1)。this
默认是要从头开始的,须要这么调用该方法calNQueens(0)spa
private void calNQueens(int row) {
if (row == n) {
printQueens(queens);
return;
}
for (int col = 0; col < n; col++) {
if (isSatisfy(row, col)) {
queens[row] = col;
calNQueens(row + 1);
}
}
}复制代码
该方法须要判断本身的横竖排,左右对角线是否有皇后。code
这里为了便于理解,因此循环里放着三个if。
private boolean isSatisfy(int row, int col) {
// System.out.println("(" + row + "," + col + ")");
int leftUp = col - 1;
int rightUp = col + 1;
for (int i = row - 1; i >= 0; --i) {
if (queens[i] == col) return false;
if (leftUp >= 0 && queens[i] == leftUp) return false;
if (rightUp < n && queens[i] == rightUp) return false;
--leftUp;
++rightUp;
}
return true;
}复制代码
private void printQueens(int[] queens) {
for (int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
if (queens[row] == col) System.out.print("1 ");
else System.out.print("0 ");
}
System.out.println();
}
System.out.println();
++count;
}复制代码
public static void main(String[] args) {
int n = 8;
SolveNQueens solveNQueens = new SolveNQueens(n);
solveNQueens.calNQueens(0);
System.out.println("共计" + solveNQueens.count + "种摆法.");
}复制代码
4皇后
八皇后(这里是包含了旋转和对称的解的解,不然是12种摆法)
您的点赞和关注是对我最大的支持,谢谢!