文章目录
N皇后
视频推荐
- 思路:
- 先把题目解释一下就是,在某个位置放入皇后之后,该位置的上下左右,左右斜上斜下的位置都不能再放入皇后了。
- 是一个经典回溯问题。
- 可以看一下代码注释,解释的比较详细了。
- 代码:
class Solution {
List<List<String>> res = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
//chess表示棋盘,.表示空的,Q表示为皇后
char[][] chess = new char[n][n];
for(char[] c : chess){
Arrays.fill(c,'.');
}
//假设从第一行开始
backtrack(chess, 0);
return res;
}
private void backtrack(char[][] board, int row){
//此时某一行已经找到了一个解
if(row == board.length){
res.add(charToList(board));
return;
}
//求出每一列的长度
int n = board[row].length;
//先假定每一列都可以放皇后
for (int col = 0; col < n; col++){
//将可以互相攻击的皇后排除
if(!isValid(board, row, col)){
continue;
}
//在当前位置放置皇后
board[row][col] = 'Q';
//对下一行进行皇后放置选择
backtrack(board, row + 1);
//撤销,即:进行回溯
board[row][col] = '.';
}
}
//判断能否在该位置放置皇后,
//因为当前位置放入了,只需要关注的是列方向、右上、左上三个位置
private boolean isValid(char[][] board, int row, int col){
int n = board.length;
//检查列的方向是否有皇后冲突
for(int i = 0; i < n; i++){
if (board[i][col] == 'Q'){
return false;
}
}
//检查右上方是否有冲突
for(int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++){
if(board[i][j] == 'Q'){
return false;
}
}
//检查左上是否有冲突
for(int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--){
if(board[i][j] == 'Q'){
return false;
}
}
//都没有
return true;
}
//将棋盘转换为list
private List charToList(char[][] board){
List<String> list = new ArrayList<>();
for(char[] c : board){
list.add(String.copyValueOf(c));
}
return list;
}
}