题目链接
N 皇后
题目描述
注意点
- 1 <= n <= 9
解答思路
- 首先想到的是使用深度优先遍历+回溯找到所有的情况,基本思路是:逐行确定Q在该行的位置,且每一行Q都是从第0列到第n - 1列全部考虑,在确定Q在任意一行的某一列时,可以根据前面行Q的位置对本行进行剪枝(在同一列可以进行剪枝,在对角线可以进行剪枝),当找到最后一行也满足条件的Q的位置,就可以写入到结果集中
- 需要注意的是怎么判断前面行中是否有Q1能与当前行Q2组成对角线
代码
class Solution {
public List<List<String>> solveNQueens(int n) {
List<List<String>> res = new ArrayList<>();
List<Integer> visitedCol = new ArrayList<>();
dfs(res, visitedCol, n, 0);
return res;
}
public void dfs(List<List<String>> res, List<Integer> visitedCol, int n, int row) {
if (row >= n) {
res.add(fillRow(visitedCol, n));
return;
}
for (int i = 0; i < n; i++) {
// 相同列
if (visitedCol.contains(i)) {
continue;
}
// 对角线
if (isDiagonal(row, i, n, visitedCol)) {
continue;
}
visitedCol.add(i);
dfs(res, visitedCol, n, row + 1);
// 回溯
visitedCol.removeLast();
}
}
public boolean isDiagonal(int row, int col, int n, List<Integer> visitedCol) {
for (int i = 0; i < visitedCol.size(); i++) {
int offset = row - i;
// 对角线的对应行列有Q
if (visitedCol.get(i) == (col - offset) || visitedCol.get(i) == (col + offset)) {
return true;
}
}
return false;
}
public List<String> fillRow(List<Integer> visitedCol, int n) {
List<String> sonRes = new ArrayList<String>();
for (int i = 0; i < n; i++) {
char[] row = new char[n];
Arrays.fill(row, '.');
// visitedCol的下标代表行
row[visitedCol.get(i)] = 'Q';
sonRes.add(new String(row));
}
return sonRes;
}
}
关键点
- 深度优先遍历+回溯的思想
- 怎么判断前面行中是否有Q1能与当前行Q2组成对角线