layout | title | gh-repo | gh-badge | tags | |||||
---|---|---|---|---|---|---|---|---|---|
post |
【经典算法问题】N皇后 |
youcoding98/youcoding98.github.io |
|
|
一、题目:N皇后
要求:
n
皇后问题 研究的是如何将n
个皇后放置在n×n
的棋盘上,并且使皇后彼此之间不能相互攻击。皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。
还是基于回溯模板去做,但要注意剪枝:1、不在同一行;2、不在同一列;3、不在同一主对角线方向上;4、不在同一副对角线方向上。
参考代码:
public class Main {
private int n;
List<List<String>> result = new ArrayList<>();
public List<List<String>> solveNQueens(int n){
if (n == 0){
return result;
}
this.n = n;
//初始化空棋盘
char[][] board = new char[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
board[i][j] = '.';
}
}
//回溯
dfs(board,0);
return result;
}
private void dfs(char[][] board,int row){
//递归结束条件
if (row == board.length){
result.add(convert(board));
return;
}
//按顺序枚举
for (int i = 0; i < n; i++) {
//1.排除不合法选择
if (!isValid(board,row,i)){
continue;
}
//做选择
board[row][i] = 'Q';
//进入下一层选择
dfs(board,row + 1);
//取消选择
board[row][i] = '.';
}
}
/**
* 判断board[row][col]是否能放置'Q'
* @param board
* @param row
* @param col
* @return
*/
private boolean isValid(char[][] board,int row,int col){
//判断这一列是否产生冲突
for (int i = 0; i < row; i++) {
if (board[i][col] == 'Q'){
return false;
}
}
//判断左上角是否产生冲突
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0 ; i--,j--){
if (board[i][j] == 'Q'){
return false;
}
}
//判断右上角是否产生冲突
for (int i = row - 1, j = col + 1; i >= 0 && j < n ; i--,j++) {
if (board[i][j] == 'Q'){
return false;
}
}
return true;
}
/**
* 将数组转化为List
* @param board
* @return
*/
private List<String> convert(char[][] board){
List<String> path = new ArrayList<>();
for (int i = 0; i < board.length; i++) {
path.add(new String(board[i]));
}
return path;
}
}