Skip to content

Commit 9aa9d81

Browse files
committed
52
1 parent 5073a51 commit 9aa9d81

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed

SUMMARY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@
5151
* [48. Rotate Image](leetCode-48-Rotate-Image.md)
5252
* [49. Group Anagrams](leetCode-49-Group-Anagrams.md)
5353
* [50. Pow(x, n)](leetCode-50-Pow.md)
54-
* [51. N-Queens](leetCode-51-N-Queens.md)
54+
* [51. N-Queens](leetCode-51-N-Queens.md)
55+
* [52. N-Queens II](leetCode-52-N-QueensII.md)

leetCode-52-N-QueensII.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# 题目描述(困难难度)
2+
3+
![](https://windliang.oss-cn-beijing.aliyuncs.com/52.jpg)
4+
5+
[上一题](https://leetcode.windliang.cc/leetCode-51-N-Queens.html)一样,只不过这次不需要返回所有结果,只需要返回有多少个解就可以。
6+
7+
# 解法一
8+
9+
我们直接把上道题的 ans 的 size 返回就可以了,此外 currentQueen.size ( ) == n 的时候,也不用去生成一个解了,直接加一个数字占位。
10+
11+
```java
12+
public int totalNQueens(int n) {
13+
List<Integer> ans = new ArrayList<>();
14+
backtrack(new ArrayList<Integer>(), ans, n);
15+
return ans.size();
16+
}
17+
18+
private void backtrack(List<Integer> currentQueen, List<Integer> ans, int n) {
19+
if (currentQueen.size() == n) {
20+
ans.add(1);
21+
return;
22+
}
23+
for (int col = 0; col < n; col++) {
24+
if (!currentQueen.contains(col)) {
25+
if (isDiagonalAttack(currentQueen, col)) {
26+
continue;
27+
}
28+
currentQueen.add(col);
29+
backtrack(currentQueen, ans, n);
30+
currentQueen.remove(currentQueen.size() - 1);
31+
}
32+
33+
}
34+
35+
}
36+
37+
private boolean isDiagonalAttack(List<Integer> currentQueen, int i) {
38+
int current_row = currentQueen.size();
39+
int current_col = i;
40+
for (int row = 0; row < currentQueen.size(); row++) {
41+
if (Math.abs(current_row - row) == Math.abs(current_col - currentQueen.get(row))) {
42+
return true;
43+
}
44+
}
45+
return false;
46+
}
47+
```
48+
49+
时间复杂度:
50+
51+
空间复杂度:
52+
53+
# 解法二
54+
55+
参考[这里](https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22))
56+
57+
既然不用返回所有解,那么我们就不需要 currentQueen 来保存当前已加入皇后的位置。只需要一个 bool 型数组,来标记列是否被占有就可以了。
58+
59+
由于没有了 currentQueen,所有不能再用之前 isDiagonalAttack 判断对角线冲突的方法了。我们可以观察下,对角线元素的情况。
60+
61+
![](https://windliang.oss-cn-beijing.aliyuncs.com/52_2.jpg)
62+
63+
可以发现对于同一条副对角线,row + col 的值是相等的。
64+
65+
对于同一条主对角线,row - col 的值是相等的。
66+
67+
我们同样可以用一个 bool 型数组,来保存当前对角线是否有元素,把它们相加相减的值作为下标。
68+
69+
对于 row - col ,由于出现了负数,所以可以加 1 个 n,由 [ - 3, 3 ] 转换为 [ 1 , 7 ]
70+
71+
```java
72+
public int totalNQueens(int n) {
73+
List<Integer> ans = new ArrayList<>();
74+
boolean[] cols = new boolean[n]; //
75+
boolean[] d1 = new boolean[2 * n]; // 主对角线
76+
boolean[] d2 = new boolean[2 * n]; // 副对角线
77+
return backtrack(0, cols, d1, d2, n, 0);
78+
}
79+
80+
private int backtrack(int row, boolean[] cols, boolean[] d1, boolean[] d2, int n, int count) {
81+
if (row == n) {
82+
count++;
83+
} else {
84+
for (int col = 0; col < n; col++) {
85+
int id1 = row - col + n; //主对角线加 n
86+
int id2 = row + col;
87+
if (cols[col] || d1[id1] || d2[id2])
88+
continue;
89+
cols[col] = true;
90+
d1[id1] = true;
91+
d2[id2] = true;
92+
count = backtrack(row + 1, cols, d1, d2, n, count);
93+
cols[col] = false;
94+
d1[id1] = false;
95+
d2[id2] = false;
96+
}
97+
98+
}
99+
return count;
100+
}
101+
102+
```
103+
104+
时间复杂度:
105+
106+
空间复杂度:
107+
108+
#
109+
110+
和上一题相比,通过三个 bool 型数组来标记是否占有,不存储具体的位置,从而解决了这道题。

0 commit comments

Comments
 (0)