题目描述:n 皇后问题 研究的是如何将
n
个皇后放置在n × n
的棋盘上,并且使皇后彼此之间不能相互攻击。给你一个整数
n
,返回 n 皇后问题 不同的解决方案的数量。示例 1:
输入:n = 4 输出:2 解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:
输入:n = 1 输出:1
提示:
1 <= n <= 9
代码思路:
backtrack(int n, int index)
:
index
表示++当前正在处理的行号++。- 如果
index
等于或超过n
,说明所有行都成功放置了皇后,找到一个符合条件的方案,res
增加 1;否则,尝试在当前行的每一列放置皇后。每放置一个皇后时,调用judge(int x, int y)
检查是否安全。 - 如果
judge
返回true
,表示当前列是安全的,将该列号添加到cur
,并继续递归处理下一行。 - 递归完成后,移除刚放置的皇后(即回溯),继续尝试放置在其他列。
judge(int x, int y)
:
- 用于判断++当前行
x
,列y
是++否安全。 - 检查之前的每一行
j
中的皇后位置ny = cur.get(j);
如果ny == y
,说明当前列有冲突。如果Math.abs(ny - y) == Math.abs(j - x)
,说明在对角线上有冲突。 - 如果都不冲突,返回
true
,表示当前位置安全。
回溯算法通过尝试在每一行的每一列放置皇后,并通过递归处理后续行来探索所有可能的放置方案。judge
方法用于在放置之前检查是否会产生冲突。最终 res
记录了所有合法的方案数量。
java
class Solution {
Integer res = 0;
LinkedList<Integer> cur = new LinkedList<>();
public int totalNQueens(int n) {
backtrack(n, 0);
return res;
}
public void backtrack(int n, int index) {
if (index >= n) {
res++;
return;
}
for (int i = 0; i < n; i++) {
if (judge(index, i)) {
cur.add(i);
backtrack(n, index + 1);
cur.removeLast();
}
}
}
public Boolean judge(int x, int y) {
for (int j = 0; j < x; j++) {
int ny = cur.get(j);
if (ny == y || Math.abs(ny - y) == Math.abs(j - x)) {
return false;
}
}
return true;
}
}