题目描述:
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
题目链接: LeetCode-51-N皇后
解题思路:和之前的回溯算法不同的是,N皇后难点是 处理的是二维数组,之前都是一维数组;
- 需要先构建一个N*N的棋盘 ,并初始化为 .
- 开始写递归 函数,还是之前的回溯三部曲,递归参数有棋盘、皇后个数和当前递归的行数row,终止条件为行数row==n
- 需要一个isValid()函数,判断在当前的棋盘上第 row 行放置皇后是否合法,具体要求注释中有
- 还需要注意一点的是,要求返回的是List,但是我们现在的棋盘是char[][],需要转化一下。
要注意的还是蛮多的,需要细心、小心、耐心!
代码实现:
class Solution {
// 难点是 处理的是二维数组,之前都是一维数组
public List<List<String>> solveNQueens(int n) {
// 建一个棋盘
char[][] chessboard = new char[n][n];
// 初始棋盘全部为 .
for (char[] c:chessboard){
Arrays.fill(c,'.');
}
backTracking(chessboard,n,0);
return res;
}
List<List<String>> res = new ArrayList<>();
/**
* @param chessboard 棋盘
* @param n 皇后个数
* @param row 当前遍历的行数
*/
public void backTracking(char[][] chessboard,int n, int row){
if (n==row){
// 加入的是 List,
res.add(Array2List(chessboard));
return;
}
// row 是本层递归中遍历的是当前的第几行?
for (int col = 0; col < n; col++) {
if (isValid(chessboard, n, row, col)){
chessboard[row][col]='Q';
backTracking(chessboard, n, row+1);
chessboard[row][col]='.';
}
}
}
// 将[][]-->List
public List<String> Array2List(char[][] chessboard){
List<String> list = new ArrayList<String>();
for (char[] c : chessboard) {
list.add(new String(c));
}
return list;
}
// 判断在当前的棋盘上第 row 行放置皇后是否合法
// 1.不能在同一行
// 2.不能在同一列
// 3.不能在同一斜线
public boolean isValid(char[][] chessboard,int n, int row, int col){
// 检查列
for (int i = 0; i < row; i++) {
if (chessboard[i][col]=='Q'){
return false;
}
}
// 检查45°
for (int i = row-1,j=col-1; i>=0 && j>=0 ; i--,j--) {
if (chessboard[i][j]=='Q'){
return false;
}
}
// 检查135°
for (int i = row-1,j=col+1; i>=0 && j<n ; i--,j++) {
if (chessboard[i][j]=='Q'){
return false;
}
}
return true;
}
}