Add subtitles to docs

This commit is contained in:
krahets
2023-07-21 21:54:51 +08:00
parent 1a55dbdf2e
commit ca5bde2b6c
16 changed files with 109 additions and 35 deletions

View File

@@ -12,12 +12,16 @@
![n 皇后问题的约束条件](n_queens_problem.assets/n_queens_constraints.png)
### 皇后放置策略
皇后的数量和棋盘的行数都为 $n$ ,因此我们容易得到第一个推论:**棋盘每行都允许且只允许放置一个皇后**。这意味着,我们可以采取逐行放置策略:从第一行开始,在每行放置一个皇后,直至最后一行结束。**此策略起到了剪枝的作用**,它避免了同一行出现多个皇后的所有搜索分支。
下图展示了 $4$ 皇后问题的逐行放置过程。受篇幅限制,下图仅展开了第一行的一个搜索分支。在搜索过程中,我们将不满足列约束和对角线约束的方案都剪枝了。
![逐行放置策略](n_queens_problem.assets/n_queens_placing.png)
### 列与对角线剪枝
为了实现根据列约束剪枝,我们可以利用一个长度为 $n$ 的布尔型数组 `cols` 记录每一列是否有皇后。在每次决定放置前,我们通过 `cols` 将已有皇后的列剪枝,并在回溯中动态更新 `cols` 的状态。
那么,如何处理对角线约束呢?设棋盘中某个格子的行列索引为 `(row, col)` ,观察矩阵的某条主对角线,**我们发现该对角线上所有格子的行索引减列索引相等**,即 `row - col` 为恒定值。换句话说,若两个格子满足 `row1 - col1 == row2 - col2` ,则这两个格子一定处在一条主对角线上。
@@ -28,6 +32,8 @@
同理,**次对角线上的所有格子的 `row + col` 是恒定值**。我们可以使用同样的方法,借助数组 `diag2` 来处理次对角线约束。
### 代码实现
根据以上分析,我们便可以写出 $n$ 皇后的解题代码。
=== "Java"
@@ -118,7 +124,7 @@
[class]{}-[func]{nQueens}
```
## 复杂度分析
### 复杂度分析
逐行放置 $n$ 次,考虑列约束,则从第一行到最后一行分别有 $n, n-1, \cdots, 2, 1$ 个选择,**因此时间复杂度为 $O(n!)$** 。实际上,根据对角线约束的剪枝也能够大幅地缩小搜索空间,因而搜索效率往往优于以上时间复杂度。