N皇后问题
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
Java代码实现:
public class SolveNQueens {
public List<List<String>> solveNQueens(int n) {
int[] state = new int[n];//用来记录n个皇后位置的数组
List<List<String>> res = new ArrayList<>();//记录结果
nQueue(res, state, 0, n);
return res;
}
public void nQueue(List<List<String>> res, int[] state, int cur, int n) {
// 递归结束的条件:当前行等于n
if (cur == n) {
List<String> temp = new ArrayList<>();//用来保存每一行的皇后的位置
for (int i = 0; i < state.length; i++) {
StringBuilder s = new StringBuilder("");
for (int j = 0; j < state.length; j++) {
if (j != state[i]) {//判断皇后是否在当前位置
s.append(".");
}else{
s.append("Q");
}
}
temp.add(s.toString());
}
res.add(temp);//用来保存所有行的皇后的位置
return;
}
for (int pos = 0; pos < state.length; pos++) {//遍历判断皇后可以放置的列
state[cur] = pos;//假设把皇后当前行的pos列
boolean flag = true;//假设可以放在当前位置
for (int col = 0; col < cur; col++) {//判断当前位置是否合法
boolean b1 = (pos == state[col]);//判断是否在同一列
boolean b2 = (Math.abs(cur - col) == Math.abs(pos - state[col]));//判断是否在对角线
if (b1 || b2) {//两个条件任意一个为true
flag = false;//说明在同一列或对角线,皇后被攻击,将flag置为false,退出本层循环,返回上一行的下一列继续进行判断
break;
}
}
if (flag == true) {//flag为true,说明当前位置合理,递归进入进入下一行
nQueue(res, state, cur + 1, n);
}
}
}
@Test
public void myTest(){
List<List<String>> lists = solveNQueens(4);
System.out.println(lists);
}
}
输出结果: