原题链接
题目描述
N皇后问题是把N个皇后放在一个N×N棋盘上,使皇后之间不会互相攻击。
即任意两个皇后都不能处于同一行、同一列或同一对角线上(正反)。
示例
输入:
4
输出:
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解析
-
3皇后问题的图解分析(3皇后问题无解)
-
可用一维数组
array[]
表示N皇后问题的解,array[i]的值
表示第i行的皇后所在的列号。例如一个满足要求的四皇后棋盘布局如下图所示,其结果array数组的值
为:[2, 4, 1, 3]。
-
判定当前结点棋盘布局是否符合要求
(1)array[i] == array[j]
,则第i行与第j行皇后在同一列上。
(2)如果第i行的皇后在第s列,第j行皇后在第t列,即array[i] = s和array[j] = t,只要|i-j| == |s-t|
(横纵坐标相减的绝对值相等),则皇后在同一对角线上。 -
遍历中要随时判定当前结点棋盘布局是否符合要求,符合要求则继续向下层遍历,直至判断得到一个满足约束条件的叶子结点(即到了最后一层),从而获得一个满足要求的棋盘布局;不符合要求的结点将被舍弃(称之为剪枝),并回溯到上一层的结点(上一层的循环)继续遍历。
参考解法
import java.util.ArrayList;
import java.util.Arrays;
public class Test {
// 放在方法外,全局变量
ArrayList<String[]> list=new ArrayList<String[]>();
/**
* @param n
* @return
*/
public ArrayList<String[]> solveNQueens(int n) {
if(n<=0){
return list;
}
int[] array=new int[n];
method(array,0);
return list;
}
/**
* 迭代过程
* @param array 表示皇后的位置,array[i] = j, 表示皇后Q在第i行、第j列
* @param k
*/
public void method(int[] array,int k){
// 表示将皇后放在了最后一行,已经生成了一个解
if(k==array.length){
String[] s=new String[array.length];
for(int i=0;i<array.length;i++){
char[] ca=new char[array.length];
Arrays.fill(ca,'.');
ca[array[i]]='Q';
s[i]=new String(ca);
}
list.add(s);
return ;
}
for(int i=0;i<array.length;i++){
// 将皇后Q放在第k行,第i列
array[k]=i;
// 满足条件则继续放在下一行
if(check(array,k)){
method(array,k+1);
}
}
}
/**
* 判断当前结点棋盘布局是否符合要求
* @param array 表示皇后的位置,array[i] = j, 表示皇后Q在第i行、第j列
* @param k
* @return
*/
public boolean check(int[] array,int k){
for(int i=0;i<k;i++){
// 前面判断皇后是否在同一列
// 后面判断是否在同一对角线(正反)。 处于对角线上的点,的横纵坐标的差,的绝对值,是相等的
if(array[i]==array[k]||k-i==Math.abs(array[i]-array[k])){
return false;
}
}
return true;
}
}
参考博客
https://blog.csdn.net/weixin_39651041/article/details/79972829