Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions codes/c/chapter_searching/binary_search_edge.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ int binarySearchInsertion(int *nums, int numSize, int target) {
if (nums[m] < target) {
i = m + 1; // target 在区间 [m+1, j] 中
} else {
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1; // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand Down Expand Up @@ -64,4 +64,4 @@ int main() {
}

return 0;
}
}
2 changes: 1 addition & 1 deletion codes/c/chapter_searching/binary_search_insertion.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ int binarySearchInsertion(int *nums, int numSize, int target) {
} else if (nums[m] > target) {
j = m - 1; // target 在区间 [i, m-1] 中
} else {
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1; // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand Down
2 changes: 1 addition & 1 deletion codes/cpp/chapter_hashing/built_in_hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ int main() {
size_t hashStr = hash<string>()(str);
cout << "字符串 " << str << " 的哈希值为 " << hashStr << "\n";

// 在 C++ 中,内置 std:hash() 仅提供基本数据类型的哈希值计算
// 在 C++ 中,内置 std::hash() 仅提供基本数据类型的哈希值计算
// 数组、对象的哈希值计算需要自行实现
}
2 changes: 1 addition & 1 deletion codes/cpp/chapter_searching/binary_search_edge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ int binarySearchInsertion(const vector<int> &nums, int target) {
if (nums[m] < target) {
i = m + 1; // target 在区间 [m+1, j] 中
} else {
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1; // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand Down
2 changes: 1 addition & 1 deletion codes/cpp/chapter_searching/binary_search_insertion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ int binarySearchInsertion(vector<int> &nums, int target) {
} else if (nums[m] > target) {
j = m - 1; // target 在区间 [i, m-1] 中
} else {
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1; // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand Down
2 changes: 1 addition & 1 deletion codes/csharp/chapter_searching/binary_search_insertion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static int BinarySearchInsertion(int[] nums, int target) {
} else if (nums[m] > target) {
j = m - 1; // target 在区间 [i, m-1] 中
} else {
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1; // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand Down
2 changes: 1 addition & 1 deletion codes/dart/chapter_searching/binary_search_insertion.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ int binarySearchInsertion(List<int> nums, int target) {
} else if (nums[m] > target) {
j = m - 1; // target 在区间 [i, m-1] 中
} else {
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1; // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand Down
2 changes: 1 addition & 1 deletion codes/go/chapter_searching/binary_search_insertion.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func binarySearchInsertion(nums []int, target int) int {
// target 在区间 [i, m-1] 中
j = m - 1
} else {
// 首个小于 target 的元素在区间 [i, m-1] 中
// 最右一个小于 target 的元素在区间 [i, m-1] 中
j = m - 1
}
}
Expand Down
2 changes: 1 addition & 1 deletion codes/java/chapter_searching/binary_search_insertion.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static int binarySearchInsertion(int[] nums, int target) {
} else if (nums[m] > target) {
j = m - 1; // target 在区间 [i, m-1] 中
} else {
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1; // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function binarySearchInsertion(nums, target) {
} else if (nums[m] > target) {
j = m - 1; // target 在区间 [i, m-1] 中
} else {
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1; // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand Down
4 changes: 2 additions & 2 deletions codes/kotlin/chapter_searching/binary_search_insertion.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fun binarySearchInsertion(nums: IntArray, target: Int): Int {
} else if (nums[m] > target) {
j = m - 1 // target 在区间 [i, m-1] 中
} else {
j = m - 1 // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1 // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand All @@ -62,4 +62,4 @@ fun main() {
val index = binarySearchInsertion(nums, target)
println("元素 $target 的插入点的索引为 $index")
}
}
}
2 changes: 1 addition & 1 deletion codes/python/chapter_searching/binary_search_insertion.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def binary_search_insertion(nums: list[int], target: int) -> int:
elif nums[m] > target:
j = m - 1 # target 在区间 [i, m-1] 中
else:
j = m - 1 # 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1 # 最右一个小于 target 的元素在区间 [i, m-1] 中
# 返回插入点 i
return i

Expand Down
2 changes: 2 additions & 0 deletions codes/ruby/chapter_backtracking/permutations_ii.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end

require 'set'

### 回溯算法:全排列 II ###
def backtrack(state, choices, selected, res)
# 当状态长度等于元素数量时,记录解
Expand Down
2 changes: 1 addition & 1 deletion codes/ruby/chapter_searching/binary_search_insertion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def binary_search_insertion(nums, target)
elsif nums[m] > target
j = m - 1 # target 在区间 [i, m-1] 中
else
j = m - 1 # 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1 # 最右一个小于 target 的元素在区间 [i, m-1] 中
end
end

Expand Down
2 changes: 1 addition & 1 deletion codes/rust/chapter_searching/binary_search_insertion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn binary_search_insertion(nums: &[i32], target: i32) -> i32 {
} else if nums[m as usize] > target {
j = m - 1; // target 在区间 [i, m-1] 中
} else {
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1; // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public func binarySearchInsertion(nums: [Int], target: Int) -> Int {
} else if nums[m] > target {
j = m - 1 // target 在区间 [i, m-1] 中
} else {
j = m - 1 // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1 // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand Down
4 changes: 2 additions & 2 deletions codes/swift/chapter_stack_and_queue/queue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ enum Queue {

/* 元素出队 */
// 使用 Array 模拟时 pop 的复杂度为 O(n)
let pool = queue.removeFirst()
print("出队元素 pop = \(pool),出队后 queue = \(queue)")
let pop = queue.removeFirst()
print("出队元素 pop = \(pop),出队后 queue = \(queue)")

/* 获取队列的长度 */
let size = queue.count
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function binarySearchInsertion(nums: Array<number>, target: number): number {
} else if (nums[m] > target) {
j = m - 1; // target 在区间 [i, m-1] 中
} else {
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
j = m - 1; // 最右一个小于 target 的元素在区间 [i, m-1] 中
}
}
// 返回插入点 i
Expand Down
4 changes: 2 additions & 2 deletions docs/chapter_appendix/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ VS Code 拥有强大的扩展包生态系统,支持大多数编程语言的运

### C/C++ 环境

1. Windows 系统需要安装 [MinGW](https://sourceforge.net/projects/mingw-w64/files/)([配置教程](https://blog.csdn.net/qq_33698226/article/details/129031241));MacOS 自带 Clang ,无须安装。
1. Windows 系统需要安装 [MinGW](https://sourceforge.net/projects/mingw-w64/files/)([配置教程](https://blog.csdn.net/qq_33698226/article/details/129031241));macOS 自带 Clang ,无须安装。
2. 在 VS Code 的插件市场中搜索 `c++` ,安装 C/C++ Extension Pack 。
3. (可选)打开 Settings 页面,搜索 `Clang_format_fallback Style` 代码格式化选项,设置为 `{ BasedOnStyle: Microsoft, BreakBeforeBraces: Attach }` 。

Expand All @@ -31,7 +31,7 @@ VS Code 拥有强大的扩展包生态系统,支持大多数编程语言的运

### C# 环境

1. 下载并安装 [.Net 8.0](https://dotnet.microsoft.com/en-us/download) 。
1. 下载并安装 [.NET 8.0](https://dotnet.microsoft.com/en-us/download) 。
2. 在 VS Code 的插件市场中搜索 `C# Dev Kit` ,安装 C# Dev Kit ([配置教程](https://code.visualstudio.com/docs/csharp/get-started))。
3. 也可使用 Visual Studio([安装教程](https://learn.microsoft.com/zh-cn/visualstudio/install/install-visual-studio?view=vs-2022))。

Expand Down
4 changes: 3 additions & 1 deletion docs/chapter_appendix/terminology.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@
| level-order traversal | 层序遍历 |
| breadth-first traversal | 广度优先遍历 |
| depth-first traversal | 深度优先遍历 |
| binary search tree | 二叉搜索树 |
| pre-order traversal | 前序遍历 |
| in-order traversal | 中序遍历 |
| post-order traversal | 后序遍历 |
| balanced binary search tree | 平衡二叉搜索树 |
| balance factor | 平衡因子 |
| heap | 堆 |
Expand Down
6 changes: 3 additions & 3 deletions docs/chapter_array_and_linkedlist/linked_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
// 构造方法
class ListNode(x: Int) {
val _val: Int = x // 节点值
val next: ListNode? = null // 指向下一个节点的引用
var next: ListNode? = null // 指向下一个节点的引用
}
```

Expand Down Expand Up @@ -658,8 +658,8 @@
// 构造方法
class ListNode(x: Int) {
val _val: Int = x // 节点值
val next: ListNode? = null // 指向后继节点的引用
val prev: ListNode? = null // 指向前驱节点的引用
var next: ListNode? = null // 指向后继节点的引用
var prev: ListNode? = null // 指向前驱节点的引用
}
```

Expand Down
2 changes: 1 addition & 1 deletion docs/chapter_backtracking/permutations_problem.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

为了实现每个元素只被选择一次,我们考虑引入一个布尔型数组 `selected` ,其中 `selected[i]` 表示 `choices[i]` 是否已被选择,并基于它实现以下剪枝操作。

- 在做出选择 `choice[i]` 后,我们就将 `selected[i]` 赋值为 $\text{True}$ ,代表它已被选择。
- 在做出选择 `choices[i]` 后,我们就将 `selected[i]` 赋值为 $\text{True}$ ,代表它已被选择。
- 遍历选择列表 `choices` 时,跳过所有已被选择的节点,即剪枝。

如下图所示,假设我们第一轮选择 1 ,第二轮选择 3 ,第三轮选择 2 ,则需要在第二轮剪掉元素 1 的分支,在第三轮剪掉元素 1 和元素 3 的分支。
Expand Down
2 changes: 1 addition & 1 deletion docs/chapter_data_structure/summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
- 原码、反码和补码是在计算机中编码数字的三种方法,它们之间可以相互转换。整数的原码的最高位是符号位,其余位是数字的值。
- 整数在计算机中是以补码的形式存储的。在补码表示下,计算机可以对正数和负数的加法一视同仁,不需要为减法操作单独设计特殊的硬件电路,并且不存在正负零歧义的问题。
- 浮点数的编码由 1 位符号位、8 位指数位和 23 位分数位构成。由于存在指数位,因此浮点数的取值范围远大于整数,代价是牺牲了精度。
- ASCII 码是最早出现的英文字符集,长度为 1 字节,共收录 127 个字符。GBK 字符集是常用的中文字符集,共收录两万多个汉字。Unicode 致力于提供一个完整的字符集标准,收录世界上各种语言的字符,从而解决由于字符编码方法不一致而导致的乱码问题。
- ASCII 码是最早出现的英文字符集,长度为 1 字节,共收录 128 个字符。GBK 字符集是常用的中文字符集,共收录两万多个汉字。Unicode 致力于提供一个完整的字符集标准,收录世界上各种语言的字符,从而解决由于字符编码方法不一致而导致的乱码问题。
- UTF-8 是最受欢迎的 Unicode 编码方法,通用性非常好。它是一种变长的编码方法,具有很好的扩展性,有效提升了存储空间的使用效率。UTF-16 和 UTF-32 是等长的编码方法。在编码中文时,UTF-16 占用的空间比 UTF-8 更小。Java 和 C# 等编程语言默认使用 UTF-16 编码。

### Q & A
Expand Down
4 changes: 2 additions & 2 deletions docs/chapter_divide_and_conquer/build_binary_tree_problem.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
根据定义,`preorder` 和 `inorder` 都可以划分为三个部分。

- 前序遍历:`[ 根节点 | 左子树 | 右子树 ]` ,例如上图的树对应 `[ 3 | 9 | 2 1 7 ]` 。
- 中序遍历:`[ 左子树 | 根节点 右子树 ]` ,例如上图的树对应 `[ 9 | 3 | 1 2 7 ]` 。
- 中序遍历:`[ 左子树 | 根节点 | 右子树 ]` ,例如上图的树对应 `[ 9 | 3 | 1 2 7 ]` 。

以上图数据为例,我们可以通过下图所示的步骤得到划分结果。

1. 前序遍历的首元素 3 是根节点的值。
2. 查找根节点 3 在 `inorder` 中的索引,利用该索引可将 `inorder` 划分为 `[ 9 | 3 1 2 7 ]` 。
2. 查找根节点 3 在 `inorder` 中的索引,利用该索引可将 `inorder` 划分为 `[ 9 | 3 | 1 2 7 ]` 。
3. 根据 `inorder` 的划分结果,易得左子树和右子树的节点数量分别为 1 和 3 ,从而可将 `preorder` 划分为 `[ 3 | 9 | 2 1 7 ]` 。

![在前序遍历和中序遍历中划分子树](build_binary_tree_problem.assets/build_tree_preorder_inorder_division.png)
Expand Down
2 changes: 1 addition & 1 deletion docs/chapter_dynamic_programming/edit_distance_problem.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

状态 $[i, j]$ 对应的子问题:**将 $s$ 的前 $i$ 个字符更改为 $t$ 的前 $j$ 个字符所需的最少编辑步数**。

至此,得到一个尺寸为 $(i+1) \times (j+1)$ 的二维 $dp$ 表。
至此,得到一个尺寸为 $(n+1) \times (m+1)$ 的二维 $dp$ 表。

**第二步:找出最优子结构,进而推导出状态转移方程**

Expand Down
2 changes: 1 addition & 1 deletion docs/chapter_dynamic_programming/knapsack_problem.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ $$

### 空间优化

由于每个状态都只与其上一行的状态有关,因此我们可以使用两个数组滚动前进,将空间复杂度从 $O(n^2)$ 降至 $O(n)$ 。
由于每个状态都只与其上一行的状态有关,因此我们可以使用两个数组滚动前进,将空间复杂度从 $O(n \times cap)$ 降至 $O(cap)$ 。

进一步思考,我们能否仅用一个数组实现空间优化呢?观察可知,每个状态都是由正上方或左上方的格子转移过来的。假设只有一个数组,当开始遍历第 $i$ 行时,该数组存储的仍然是第 $i-1$ 行的状态。

Expand Down
2 changes: 1 addition & 1 deletion docs/chapter_dynamic_programming/summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@
**编辑距离问题**

- 编辑距离(Levenshtein 距离)用于衡量两个字符串之间的相似度,其定义为从一个字符串到另一个字符串的最少编辑步数,编辑操作包括添加、删除、替换。
- 编辑距离问题的状态定义为将 $s$ 的前 $i$ 个字符更改为 $t$ 的前 $j$ 个字符所需的最少编辑步数。当 $s[i] \ne t[j]$ 时,具有三种决策:添加、删除、替换,它们都有相应的剩余子问题。据此便可以找出最优子结构与构建状态转移方程。而当 $s[i] = t[j]$ 时,无须编辑当前字符。
- 编辑距离问题的状态定义为将 $s$ 的前 $i$ 个字符更改为 $t$ 的前 $j$ 个字符所需的最少编辑步数。当 $s[i-1] \ne t[j-1]$ 时,具有三种决策:添加、删除、替换,它们都有相应的剩余子问题。据此便可以找出最优子结构与构建状态转移方程。而当 $s[i-1] = t[j-1]$ 时,无须编辑当前字符。
- 在编辑距离中,状态依赖其正上方、正左方、左上方的状态,因此空间优化后正序或倒序遍历都无法正确地进行状态转移。为此,我们利用一个变量暂存左上方状态,从而转化到与完全背包问题等价的情况,可以在空间优化后进行正序遍历。
2 changes: 1 addition & 1 deletion docs/chapter_greedy/fractional_knapsack_problem.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
[file]{fractional_knapsack}-[class]{}-[func]{fractional_knapsack}
```

内置排序算法的时间复杂度通常为 $O(\log n)$ ,空间复杂度通常为 $O(\log n)$ 或 $O(n)$ ,取决于编程语言的具体实现。
内置排序算法的时间复杂度通常为 $O(n \log n)$ ,空间复杂度通常为 $O(\log n)$ 或 $O(n)$ ,取决于编程语言的具体实现。

除排序之外,在最差情况下,需要遍历整个物品列表,**因此时间复杂度为 $O(n)$** ,其中 $n$ 为物品数量。

Expand Down
2 changes: 1 addition & 1 deletion docs/chapter_greedy/greedy_algorithm.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,4 @@
- **分数背包问题**:给定一组物品和一个载重量,你的目标是选择一组物品,使得总重量不超过载重量,且总价值最大。如果每次都选择性价比最高(价值 / 重量)的物品,那么贪心算法在一些情况下可以得到最优解。
- **股票买卖问题**:给定一组股票的历史价格,你可以进行多次买卖,但如果你已经持有股票,那么在卖出之前不能再买,目标是获取最大利润。
- **霍夫曼编码**:霍夫曼编码是一种用于无损数据压缩的贪心算法。通过构建霍夫曼树,每次选择出现频率最低的两个节点合并,最后得到的霍夫曼树的带权路径长度(编码长度)最小。
- **Dijkstra 算法**:它是一种解决给定源顶点到其余各顶点的最短路径问题的贪心算法。
- **Dijkstra 算法**:在所有边的权重均为非负数的图中,它是一种解决给定源顶点到其余各顶点的最短路径问题的贪心算法。
2 changes: 1 addition & 1 deletion docs/chapter_greedy/max_product_cutting_problem.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ $$
1. 输入整数 $n$ ,从其不断地切分出因子 $3$ ,直至余数为 $0$、$1$、$2$ 。
2. 当余数为 $0$ 时,代表 $n$ 是 $3$ 的倍数,因此不做任何处理。
3. 当余数为 $2$ 时,不继续划分,保留。
4. 当余数为 $1$ 时,由于 $2 \times 2 > 1 \times 3$ ,因此应将最后一个 $3$ 替换为 $2$ 。
4. 当余数为 $1$ 时,由于 $2 \times 2 > 1 \times 3$ ,因此应将最后一个 $3$ 和余数 $1$ 替换为两个 $2$ 。

### 代码实现

Expand Down
2 changes: 1 addition & 1 deletion docs/chapter_hashing/hash_algorithm.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ $$
size_t hashStr = hash<string>()(str);
// 字符串“Hello 算法”的哈希值为 15466937326284535026

// 在 C++ 中,内置 std:hash() 仅提供基本数据类型的哈希值计算
// 在 C++ 中,内置 std::hash() 仅提供基本数据类型的哈希值计算
// 数组、对象的哈希值计算需要自行实现
```

Expand Down
2 changes: 1 addition & 1 deletion docs/chapter_hashing/summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
- 负载因子定义为哈希表中元素数量除以桶数量,反映了哈希冲突的严重程度,常用作触发哈希表扩容的条件。
- 链式地址通过将单个元素转化为链表,将所有冲突元素存储在同一个链表中。然而,链表过长会降低查询效率,可以通过进一步将链表转换为红黑树来提高效率。
- 开放寻址通过多次探测来处理哈希冲突。线性探测使用固定步长,缺点是不能删除元素,且容易产生聚集。多次哈希使用多个哈希函数进行探测,相较线性探测更不易产生聚集,但多个哈希函数增加了计算量。
- 不同编程语言采取了不同的哈希表实现。例如,Java 的 `HashMap` 使用链式地址,而 Python 的 `Dict` 采用开放寻址。
- 不同编程语言采取了不同的哈希表实现。例如,Java 的 `HashMap` 使用链式地址,而 Python 的 `dict` 采用开放寻址。
- 在哈希表中,我们希望哈希算法具有确定性、高效率和均匀分布的特点。在密码学中,哈希算法还应该具备抗碰撞性和雪崩效应。
- 哈希算法通常采用大质数作为模数,以最大化地保证哈希值均匀分布,减少哈希冲突。
- 常见的哈希算法包括 MD5、SHA-1、SHA-2 和 SHA-3 等。MD5 常用于校验文件完整性,SHA-2 常用于安全应用与协议。
Expand Down
2 changes: 1 addition & 1 deletion docs/chapter_heap/build_heap.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

下面,我们来尝试推算第二种建堆方法的时间复杂度。

- 假设完全二叉树的节点数量为 $n$ ,则叶节点数量为 $(n + 1) / 2$ ,其中 $/$ 为向下整除。因此需要堆化的节点数量为 $(n - 1) / 2$ 。
- 假设完全二叉树的节点数量为 $n$ ,则叶节点数量为 $(n + 1) / 2$ ,其中 $/$ 为向下整除。因此需要堆化的节点数量为 $n / 2$ 。
- 在从顶至底堆化的过程中,每个节点最多堆化到叶节点,因此最大迭代次数为二叉树高度 $\log n$ 。

将上述两者相乘,可得到建堆过程的时间复杂度为 $O(n \log n)$ 。**但这个估算结果并不准确,因为我们没有考虑到二叉树底层节点数量远多于顶层节点的性质**。
Expand Down
Loading
Loading