Skip to content

Commit 5073a51

Browse files
committed
51
1 parent 4eed6e8 commit 5073a51

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

SUMMARY.md

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

leetCode-51-N-Queens.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# 题目描述(困难难度)
2+
3+
![](https://windliang.oss-cn-beijing.aliyuncs.com/51.jpg)
4+
5+
经典的 N 皇后问题。意思就是摆皇后的位置,每行每列以及对角线只能出现 1 个皇后。输出所有的情况。
6+
7+
# 解法一 回溯法
8+
9+
比较经典的回溯问题了,我们需要做的就是先在第一行放一个皇后,然后进入回溯,放下一行皇后的位置,一直走下去,如果已经放的皇后的数目等于 n 了,就加到最后的结果中。然后再回到上一行,变化皇后的位置,然后去找其他的解。
10+
11+
期间如果遇到当前行所有的位置都不能放皇后了,就再回到上一行,然后变化皇后的位置。再返回到下一行。
12+
13+
说起来可能还费力些,直接看代码吧。
14+
15+
```java
16+
public List<List<String>> solveNQueens(int n) {
17+
List<List<String>> ans = new ArrayList<>();
18+
backtrack(new ArrayList<Integer>(), ans, n);
19+
return ans;
20+
}
21+
22+
private void backtrack(List<Integer> currentQueen, List<List<String>> ans, int n) {
23+
// 当前皇后的个数是否等于 n 了,等于的话就加到结果中
24+
if (currentQueen.size() == n) {
25+
List<String> temp = new ArrayList<>();
26+
for (int i = 0; i < n; i++) {
27+
char[] t = new char[n];
28+
Arrays.fill(t, '.');
29+
t[currentQueen.get(i)] = 'Q';
30+
temp.add(new String(t));
31+
}
32+
ans.add(temp);
33+
return;
34+
}
35+
//尝试每一列
36+
for (int col = 0; col < n; col++) {
37+
//当前列是否冲突
38+
if (!currentQueen.contains(col)) {
39+
//判断对角线是否冲突
40+
if (isDiagonalAttack(currentQueen, col)) {
41+
continue;
42+
}
43+
//将当前列的皇后加入
44+
currentQueen.add(col);
45+
//去考虑下一行的情况
46+
backtrack(currentQueen, ans, n);
47+
//将当前列的皇后移除,去判断下一列
48+
//进入这一步就是两种情况,下边的行走不通了回到这里或者就是已经拿到了一个解回到这里
49+
currentQueen.remove(currentQueen.size() - 1);
50+
}
51+
52+
}
53+
54+
}
55+
56+
private boolean isDiagonalAttack(List<Integer> currentQueen, int i) {
57+
// TODO Auto-generated method stub
58+
int current_row = currentQueen.size();
59+
int current_col = i;
60+
//判断每一行的皇后的情况
61+
for (int row = 0; row < currentQueen.size(); row++) {
62+
//左上角的对角线和右上角的对角线,差要么相等,要么互为相反数,直接写成了绝对值
63+
if (Math.abs(current_row - row) == Math.abs(current_col - currentQueen.get(row))) {
64+
return true;
65+
}
66+
}
67+
return false;
68+
}
69+
```
70+
71+
时间复杂度:
72+
73+
空间复杂度:
74+
75+
上边我们只判断了列冲突和对角线冲突,至于行冲突,由于我们采取一行一行加皇后,所以一行只会有一个皇后,不会产生冲突。
76+
77+
#
78+
79+
最早接触的一类问题了,学回溯法的话,一般就会以这个为例,所以思路上不会遇到什么困难。

0 commit comments

Comments
 (0)