问题描述:
N皇后问题,研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击(任何两个皇后都不能处于同一条横行、纵行或斜线上。)。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
例如:n=4,共有两种结果
力扣第51题便是此题
class Solution {
public List<List<String>> solveNQueens(int n) {
List<List<String>> res = new ArrayList<>();
Set<Integer> leftDJ = new HashSet<>();//左对角
Set<Integer> rightDJ = new HashSet<>();//右对角
Set<Integer> Lie = new HashSet<>();//列
boolean[][] board = new boolean[n][n];
backtrac(res, 0, n, leftDJ, rightDJ, Lie, board);//0表示每一行开始的位置
return res;
}
private void backtrac(List<List<String>> res, int i, int n, Set<Integer> leftDJ, Set<Integer> rightDJ, Set<Integer> Lie, boolean[][] board) {
if (i == n) {//i=n表示已经到了最后一行。每一行不管怎么放,都只能放一个皇后
get_result(n, board, res);
return;
}
for (int j = 0; j < n; j++) {
if (leftDJ.contains(i + j) || Lie.contains(j) || rightDJ.contains(i - j)) {
continue;
}
board[i][j] = true; //在第i行j列放一个皇后
leftDJ.add(i + j); //左对角线上,各个位置的行列坐标加起来数值相同。如果leftDJ里包含这个值,说明当前位置的左对角线上已经有一个皇后。
rightDJ.add(i - j);//右对角线各个坐标的行列值相减,相同。和判断左对角线原理相同
Lie.add(j);
backtrac(res, i + 1, n, leftDJ, rightDJ, Lie, board);//立即进入下一行。比如i=0.第一行填了一个皇后,那么这一行后面的就不用考虑了,直接进入第二行回溯
Lie.remove(j);
leftDJ.remove(i + j);
rightDJ.remove(i - j);
board[i][j] = false;
}
}
public void get_result(int n, boolean[][] board, List<List<String>> res) {
List<String> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < n; j++) {
if (board[i][j] == true) {
sb.append('Q');
} else {
sb.append('.');
}
}
list.add(sb.toString());
}
res.add(list);
}
}