LeetCode 51 N皇后
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
解法思路:递归+回溯
1、从第0行,第0列开始插入皇后
2、行数++
3、依次遍历当前行所有列找到允许插入的列插入皇后,当前网格数记为1,重复2~3
4、若遍历完当前行所有列没有找到能插入的点,则结束当前方法返回上一层,在上一层寻找下一个能插入的点,重复2~4
5、直至当前行数已经遍历完成,存入list中,并返回上一层寻找下一个能插入的点,重复2~5
class Solution {
List<List<String>> list = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
int [][] grid = new int [n][n];
HashSet<Integer> column = new HashSet<>();
//左上到右下-7~7(x-y)
HashSet<Integer> line1 = new HashSet<>();
//右上到左下0~14(x+y)
HashSet<Integer> line2 = new HashSet<>();
dfs(grid,0,n,column,line1,line2);
return list;
}
public void dfs(int [][] grid,int i,int n,HashSet<Integer> column
,HashSet<Integer> line1,HashSet<Integer> line2){
if(i >= n){
toAdd(grid,n);
return ;
}
for(int y = 0; y < n; y++){
if(column.contains(y) || line1.contains(i-y) || line2.contains(i+y)){
continue;
}
grid[i][y] = 1;
column.add(y);
line1.add(i-y);
line2.add(i+y);
dfs(grid,i+1,n,column,line1,line2);
grid[i][y] = 0;
column.remove(y);
line1.remove(i-y);
line2.remove(i+y);
}
}
public void toAdd(int [][] grid,int n){
List<String> list2 = new ArrayList<>();
for(int i = 0; i < n; i++){
String s = "";
for(int j = 0; j < n; j++){
if(grid[i][j] == 1){
s += "Q";
}else{
s += ".";
}
}
list2.add(s);
}
list.add(list2);
}
}
N皇后的解决方案数,方法类似
class Solution {
int resulut = 0;
public int totalNQueens(int n) {
boolean [] line = new boolean [n];
int [] p = new int [n];
int row = 0;
dfs(0,n,line,p);
return resulut;
}
public void dfs(int row, int n, boolean [] line, int [] p){
if(row >= n){
resulut++;
return;
}
for(int i = 0; i < n; i++){
boolean flag = true;
if(!line[i]){
for(int j = 0; j < row; j++){
if(Math.abs(row - j) == Math.abs(i - p[j])){
flag = false;
break;
}
}
if(flag){
p[row] = i;
line[i] = true;
dfs(row + 1,n,line,p);
line[i] = false;
}
}
}
}
}