题目链接:https://leetcode-cn.com/problems/n-queens/
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中
'Q'
和'.'
分别代表了皇后和空位。示例:
输入: 4 输出: [ [".Q..", // 解法 1 "...Q", "Q...", "..Q."], ["..Q.", // 解法 2 "Q...", "...Q", ".Q.."] ] 解释: 4 皇后问题存在两个不同的解法。
ac的代码,代码注释里面有部分思路
public List<List<String>> solveNQueens(int n) {
List<List<String>> result = new ArrayList<>();
int[] x = new int[n];
reback(result, x, 0);
return result;
}
// 回溯算法
// 1、由于每一行一定都会有一个皇后,因此只需要一个x[n]便能确定每个皇后的位置,x数组记录每一行的横座标
// 2、一行一行向下递归,rowNum记录行号
// 3、check方法对rowNum行的皇后位置进行校验
public static void reback(List<List<String>> result, int[] x, int rowNum) {
if (rowNum == x.length) {
generateResult(result, x);
return;
}
int temp = x[rowNum];
for (int i = 0, length = x.length; i < length; i++) {
x[rowNum] = i;
if (check(x, rowNum)) {
reback(result, x, rowNum + 1);
}
x[rowNum] = temp;
}
}
// 校验
// 0、只需要验证到row的前一行(因为只有row之前放皇后了)
// 1、x[i] == x[row] 校验是否为相同列
// 2、row - i == Math.abs(x[row] - x[i]) 校验与主对角线和副对角线是否相同
public static boolean check(int[] x, int row) {
for (int i = 0; i < row; i++) {
if (x[i] == x[row] || row - i == Math.abs(x[row] - x[i])) {
return false;
}
}
return true;
}
//生成结果
public static void generateResult(List<List<String>> result, int[] x) {
List<String> temp = new ArrayList<>();
for (int i = 0,length = x.length; i < length; i++) {
StringBuffer stringBuffer = new StringBuffer();
for (int j = 0; j < length; j++) {
if(j != x[i]) {
stringBuffer.append('.');
continue;
}
stringBuffer.append('Q');
}
temp.add(stringBuffer.toString());
}
result.add(temp);
}