描述
n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击。
给定一个整数n,返回所有不同的n皇后问题的解决方案。
每个解决方案包含一个明确的n皇后放置布局,其中“Q”和“.”分别表示一个女王和一个空位置。
样例
对于4皇后问题存在两种解决的方案:
[
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],
["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
挑战
你能否不使用递归完成?
思路: 首先如果满足每一行,每一列,每一斜边都不冲突的话,那么每一行都只能有一个解。
然后我们来分配每一列的解,每一列的解从1-n依次判断分配,如果满足条件,就分配。这是一个DFS问题。
Java代码如下:
public class N_Queens {
public static List<List<String>> solveNQueens(int n) {
// write your code here
// suppose 每一行一个,现在判断每一列
List<List<String>> res = new ArrayList<>();
int[][] arr = new int[n][n];
helper(0, arr, res, n);
return res;
}
public static void helper(int start, int[][] arr, List<List<String>> res, int n){
if(start==arr.length){
// 保存到res
List<String> list = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < arr[0].length; j++) {
if(arr[i][j]==0){
sb.append(".");
}else{
sb.append("Q");
}
}
list.add(sb.toString());
}
res.add(list);
}
for (int i = 0; i < n; i++) {
if(judge(arr, start, i)) {
arr[start][i] = 1;
helper(start + 1, arr, res, n);
arr[start][i] = 0;
}
}
}
public static boolean judge(int[][] arr, int start, int i){
int n = arr.length;
for (int j = 0; j < arr.length; j++) {
if(arr[j][i]==1){
return false;
}
}
// 判断斜着的没有重复的
int a = start+1, b = i+1;
while (a<n&&b<n){
if(arr[a][b]==1){
return false;
}
a++; b++;
}
a = start-1; b = i-1;
while (a>=0&&b>=0){
if(arr[a][b]==1){
return false;
}
a--; b--;
}
a = start+1; b = i-1;
while (a<n&&b<n&&a>=0&&b>=0){
if(arr[a][b]==1){
return false;
}
a++; b--;
}
a = start-1; b = i+1;
while (a<n&&b<n&&a>=0&&b>=0){
if(arr[a][b]==1){
return false;
}
a--; b++;
}
return true;
}
public static void main(String[] args) {
System.out.println(solveNQueens(4));
}
}
结果:
[[.Q.., ...Q, Q..., ..Q.], [..Q., Q..., ...Q, .Q..]]