spot_taken[row,col] == false
End If
Next col
Next row
//到这一步,当前棋盘没有摆法正确,也就是没有可行解
Return false
Next EightQueens
这里的IsLeagl方法用来考察这个方案,也就是当前棋盘种是否符合规则,也就是是否有皇后出现在同一行、同一列、或同一斜线上。
如果这不是一个完整解,程序会遍历所有行和所有列,如果这个位置没有皇后就将皇后放上去,然后递归调用检查当前棋盘是否合理,如果合理,就会在下一层递归继续扩展。。。。
直到最后一层递归调用返回为true,那么程序就会找到一组完整解,所有的递归调用都会返回true(不会走下一步的取出皇后)
如果某一层返回为false,那么就会走下一步的取出皇后,讨论下一个可能解。
Java实现
/**
-
@Author: Ember
-
@Date: 2021/3/13 16:32
-
@Description: 八皇后问题
*/
public class EightQueens {
/**
-
使用二维数组代表棋盘
-
1:代表已经摆了皇后
-
0:代表未摆放
*/
private int[][] spotTaken;
/**
- 标识摆第几个皇后
*/
private int numQueen;
/**
- 八皇后满足条件
*/
private final int EIGHT_QUEEN = 8;
/**
- 初始化棋盘和第几个皇后
*/
public EightQueens() {
//对棋盘进行初始化
spotTaken = new int[8][8];
for (int i = 0; i < spotTaken.length; i++) {
for (int j = 0; j < spotTaken.length; j++) {
spotTaken[i][j] = 0;
}
}
numQueen = 0;
}
/**
-
检验新摆的皇后是否合理
-
@param row
-
@param column
-
@return
*/
private boolean isLegal(int row,int column){
//检查行列
for (int i = 0; i < this.spotTaken.length; i++) {
//检查行
if(i != column && this.spotTaken[row][i] == 1){
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
return false;
}
//检查列
if (i != row && this.spotTaken[i][column] == 1){
return false;
}
}
//检查主对角线下方
for(int i = row,j = column; i < spotTaken.length && j < spotTaken.length;i++,j++){
//检查主对角线的下方
if(i != row && j != column && spotTaken[i][j] == 1){
return false;
}
}
//检查主对角线上方
for(int i = row,j = column; i >= 0 && j >= 0;i–,j–){
if(i != row && j != column && spotTaken[i][j] == 1){
return false;
}
}
//检查副对角线下方
for(int i = row,j = column;i < spotTaken.length && j >= 0;i++,j–){
if( i != row && j != column && spotTaken[i][j] == 1){
return false;
}
}
//检查副对角线上方
for(int i = row,j = column;i >= 0 && j < spotTaken.length;i–,j++){
if( i != row && j != column && spotTaken[i][j] == 1){
return false;
}
}
return true;
}
/**
-
检查皇后是否可以放在这个位置
-
@param row
-
@param column
-
@return
*/
private boolean isCanPut(int row,int column){
return this.spotTaken[row][column] != 1;
}
/**
-
放入一个皇后,
-
@return
*/
private boolean dealEightQueen(int numQueen,int[][] spotTaken){
//检验是否已经放了八个皇后
if(numQueen == EIGHT_QUEEN){
return true;
}
for (int i = 0; i < spotTaken.length; i++) {
for (int j = 0; j < spotTaken.length; j++) {
//检验该位置是否可以放皇后且是否合理
if(isCanPut(i,j) && isLegal(i,j)){
//如果可以放且位置合理,就放入皇后
spotTaken[i][j] = 1;
//递归寻找另一个可能解,即下一个皇后可能存在的位置
if(dealEightQueen(numQueen+1,spotTaken)){
return true;
}
//如果下一层递归的解都不符合,那么就要回到这一层,将皇后移除,寻找另一个解