n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-queens
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
回溯法:
int[] queens;//存储每一行的皇后所在的列
int[] cols;//标识每一个列是否可用,-1表示可用,1表示不可用
int[] hills;
int[] dales;
//每个点其左对角元素行与列和都是一样的,右对角元素行与列的差都是一样的,用hills与dales分别标识
int n;
List<List<String>> output;
public void placeQueen(int row,int col){
queens[row]=col;
cols[col]=1;
hills[row+col]=1;
dales[row-col+n]=1;
}
public void removeQueen(int row,int col){
queens[row]=-1;
cols[col]=-1;
hills[row+col]=-1;
dales[row-col+n]=-1;
}
public boolean isNotUnderAttack(int row,int col){
if(cols[col]==-1&&hills[col+row]==-1&&dales[row-col+n]==-1)
return true;
return false;
}
public void backTrack(int row){
for(int col=0;col<n;col++){
if(isNotUnderAttack(row, col)){
placeQueen(row, col);
if(row+1==n){
add();
}
else backTrack(row+1);
removeQueen(row, col);
}
}
}
public void add(){
List<String> res=new ArrayList<>();
for(int i=0;i<n;i++){
StringBuffer sb=new StringBuffer();
for(int j=0;j<n;j++){
if(queens[i]==j){
sb.append("Q");
}
else{
sb.append(".");
}
}
res.add(sb.toString());
}
output.add(res);
}
public List<List<String>> solveNQueens(int n) {
this.n=n;
queens=new int[n];
hills=new int[n*2];
dales=new int[n*2];
cols=new int[n];
for(int i=0;i<n;i++){
queens[i]=-1;
cols[i]=-1;
}
for(int i=0;i<2*n;i++){
dales[i]=-1;
hills[i]=-1;
}
output=new ArrayList<>();
backTrack(0);
return output;
}