思路
首先要知道在棋盘的什么位子可以放置棋子。当前位子所在的列所在的行以及其所在的两个对角线如果有棋子存在就不能放了。所以isVaild()函数已经就是这样写的。
然后就是回溯的一般步骤。需要注意的时,在放置棋子时,要进行判断,如果满足条件就放置,如果不满足就不放,并且回溯是在满足条件的基础上进行的(可以参照图片来理解)。
代码随想录的图如下:
代码
class Solution {
List<List<String>> res = new ArrayList<>();
List<String> path = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
char[][] nums = new char[n][n];
for (char[] c : nums) {
Arrays.fill(c, '.');
}
fun(n,nums,0);
return res;
}
public void fun(int n,char[][] chessboard,int row){
if (row == n) {
res.add(Array2List(chessboard));
return;
}
for (int col = 0;col < n; col++) {
if (isValid(row, col, n, chessboard)) {
chessboard[row][col] = 'Q';
fun(n,chessboard, row+1);
chessboard[row][col] = '.';
}
}
}
public boolean isValid(int row,int col,int n,char[][]chessboard){
// 检查列
for (int i=0; i<row; ++i) { // 相当于剪枝
if (chessboard[i][col] == 'Q') {
return false;
}
}
// 检查行
for(int i =0;i<col;i++){
if(chessboard[row][i] == '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-1; i--, j++) {
if (chessboard[i][j] == 'Q') {
return false;
}
}
return true;
}
public List Array2List(char[][] chessboard) {
List<String> list = new ArrayList<>();
for (char[] c : chessboard) {
list.add(String.copyValueOf(c));
}
return list;
}
}