难度:hard
好久没有过hard题目了,还是很开心!
本题的难点在于如何对一个二维数组进行回溯,我们的思路是以chessBoard的行hang为树的每一层,每次递归中的循环就是遍历这一层的每个元素,然后进入下一次递归(进入下一行);理解了这个,问题也就迎刃而解了。
class Solution {
private List<List<String>> ans = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
char[][] chessBoard = new char[n][n];
// 初始化
char[] chessList = new char[n];
// 这样初始化不对
// Arrays.fill(chessList, '.');
// Arrays.fill(chessBoard, chessList);
for (char[] c : chessBoard) {
Arrays.fill(c, '.');
}
backtracking(chessBoard, n, 0);
return ans;
}
public void backtracking(char[][] chessBoard, int n, int row) {
if (row == n) {
ans.add(Array2List(chessBoard));
return;
}
for (int i = 0; i < n; i++) {
if (isValid(chessBoard, n, row, i)) {
chessBoard[row][i] = 'Q';
backtracking(chessBoard, n, row + 1);
chessBoard[row][i] = '.';
}
}
}
public boolean isValid(char[][] chessBoard, int n, int row, int col) {
// 检查列是否合法
for (int i = row - 1; i >= 0; i--) {
if (chessBoard[i][col] == 'Q') {
return false;
}
}
// 检查45度是否合法
for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
if (chessBoard[i][j] == 'Q') {
return false;
}
}
// 检查135度是否合法
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (chessBoard[i][j] == 'Q') {
return false;
}
}
return true;
}
// 将二维字符数组转化为List<String>类型
public List<String> Array2List(char[][] chessBoard) {
List<String> list = new ArrayList<>();
// 一行一行读取
for (char[] c: chessBoard) {
list.add(String.copyValueOf(c));
}
return list;
}
}