N皇后问题是一个非常经典的问题,即如何能够在N*N的棋盘上放置N个皇后,使得任何一个皇后都无法直接吃掉其他的皇后。为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。注意仅当 N= 1 或N≥ 4 时问题有解。
解题思路
这个问题依然可以用递归来解决。由于每一行只能放置一个皇后,所以可以尝试在从每一行的N个位置上尝试放置皇后,直到放满N个皇后。在尝试的过程中,维护三个数组表示该位置是否可以放置皇后,其中列用自身表示,主对角线上用横竖坐标的差表示,副对角线上用横竖坐标的和表示。
JAVA代码实现
class Solution {
boolean[] col = null;
boolean[] dia1 = null;
boolean[] dia2 = null;
List<List<String>> res = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
col = new boolean[n];
dia1 = new boolean[2*n-1];
dia2 = new boolean[2*n-1];
dfs(n, 0, new ArrayList<>());
return res;
}
public void dfs(int n,int row,List<Integer> st) {
if(row==n){
res.add(aux(n, st));
return;
}
for(int i=0;i<n;i++){
if(!col[i]&&!dia1[row-i+n-1]&&!dia2[row+i]){
col[i] = true;
dia1[row-i+n-1] = true;
dia2[row+i] = true;
st.add(i);
dfs(n, row+1, st);
st.remove(st.size()-1);
col[i] = false;
dia1[row-i+n-1] = false;
dia2[row+i] = false;
}
}
}
public List<String> aux(int n,List<Integer> st) {
char[] t = new char[n];
List<String> temp = new ArrayList<>();
for(int i=0;i<n;i++) t[i] = '.';
for(int i=0;i<n;i++){
int k = st.get(i);
t[k] = 'Q';
temp.add(String.valueOf(t));
t[k] = '.';
}
return temp;
}
}