题目描述(苦难难度)
经典的 N 皇后问题。意思就是摆皇后的位置,每行每列以及对角线只能出现 1 个皇后。输出所有的情况。
解法一 回溯法
比较经典的回溯问题了,我们按列来放置皇后,我们需要做的就是先在第一列的某个位置放一个皇后,接着在第二列的某个位置放置皇后,如果在后面出现不满足的情况,则进入回溯,重新调整放入的位置,一直走下去,如果已经放的皇后的数目等于 n 了,就加到最后的结果中。然后再回到上一行,变化皇后的位置,然后去找其他的解。
期间如果遇到当前行所有的位置都不能放皇后了,就再回到上一行,然后变化皇后的位置。再返回到下一行。
说起来可能还费力些,直接看代码吧。
import java.util.*;
public class N_Queens {
public static List<List<String>> solveNQueens(int n){
char[][]board=new char[n][n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
board[i][j]='.';
}
}
List<List<String>> res = new ArrayList<List<String>>();
dfs(board,0,res);
return res;
}
private static void dfs(char[][]board,int colIndex,List<List<String>>res){
if(colIndex==board.length){
res.add(construct(board));
return;
}
for(int i=0;i<board.length;i++){
if(validate(board,i,colIndex)){
board[i][colIndex]='Q';
dfs(board,colIndex+1,res);
board[i][colIndex]='.';
}
}
}
private static boolean validate(char[][]board,int x,int y){
for(int i=0;i<board.length;i++){
for(int j=0;j<y;j++){
if(board[i][j]=='Q' &&(x+j==y+i||x+y==i+j || x==i))
return false;
}
}
return true;
}
private static List<String> construct(char[][]board){
List<String> res =new LinkedList<String>();
for(int i=0;i<board.length;i++){
String s=new String(board[i]);
res.add(s);
}
return res;
}
public static void main(String args[]){
int n =4;
List<List<String>> ans =solveNQueens(n);
System.out.println(ans);
}
}
参考文献
- https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution