- 题目:
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
-
示例 1:
输入:n = 4 输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] 解释:如上图所示,4 皇后问题存在两个不同的解法。
-
示例 2:
输入:n = 1 输出:[["Q"]]
-
提示
1 <= n <= 9
- 皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。
思路 :
- 回溯算法。在放每个皇后的时候都判断能不能被之前放置的皇后攻击到
样例代码
public List<List<String>> solveNQueens(int n) {
char[][] arr = new char[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
arr[i][j] = '.';
}
}
List<List<String>> result = new ArrayList<>();
dfs(result, arr, 0, 0);
return result;
}
/**
* @param result 结果集
* @param arr 棋盘
* @param x 第x行
* @param y 第y列
*/
private void dfs(List<List<String>> result, char[][] arr, int x, int y) {
// y代表已经放置了几个皇后
if (x >= arr.length || y >= arr.length) {
List<String> list = new ArrayList<>(arr.length);
for (char[] chars : arr) {
list.add(new String(chars));
}
result.add(list);
return;
}
for (int i = x; i < arr.length; i++) {
if (isCanPut(arr, i, y)) {
arr[i][y] = 'Q';
// 表示该位置可以放一个皇后,到下一行继续放
dfs(result, arr, 0, y + 1);
// 记得还原
arr[i][y] = '.';
}
}
}
/**
* 判断这个位置是否可以放置皇后
* @param arr 棋盘
* @param x
* @param y
* @return
*/
private boolean isCanPut(char[][] arr, int x, int y) {
int y2;
// 判断在这个位置是否可以放皇后
for (int j = 1; j < arr.length; j++) {
y2 = y - j;
if (y2 < 0) {
// 可以放
return true;
}
// 判断左上方是否已经放置了皇后
if (x - j >= 0 && arr[x - j][y2] == 'Q') {
return false;
}
// 右上方
if (x + j < arr.length && arr[x + j][y2] == 'Q') {
return false;
}
// 正上方
if (arr[x][y2] == 'Q') {
return false;
}
}
return true;
}