This commit is contained in:
krahets
2023-02-09 04:43:12 +08:00
parent af3542e3c0
commit 4d2575be7a
18 changed files with 264 additions and 156 deletions

View File

@@ -32,10 +32,16 @@ comments: true
既然实际测试具有很大的局限性,那么我们是否可以仅通过一些计算,就获知算法的效率水平呢?答案是肯定的,我们将此估算方法称为「复杂度分析 Complexity Analysis」或「渐近复杂度分析 Asymptotic Complexity Analysis」。
**复杂度分析评估随着输入数据量的增长,算法的运行时间和占用空间的增长趋势**。根据时间和空间两方面,复杂度可分为「时间复杂度 Time Complexity」和「空间复杂度 Space Complexity」。
**复杂度分析评估的是算法运行效率随着输入数据量增多时的增长趋势**。这句话有些拗口,我们可以将其分为三个重点来理解:
- “算法运行效率”可分为“运行时间”和“占用空间”,进而可将复杂度分为「时间复杂度 Time Complexity」和「空间复杂度 Space Complexity」。
- “随着输入数据量增多时”代表复杂度与输入数据量有关,反映算法运行效率与输入数据量之间的关系;
- “增长趋势”表示复杂度分析不关心算法具体使用了多少时间或占用了多少空间,而是给出一种“趋势性分析”;
**复杂度分析克服了实际测试方法的弊端**。一是独立于测试环境,分析结果适用于所有运行平台。二是可以体现不同数据量下的算法效率,尤其是可以反映大数据量下的算法性能。
如果感觉对复杂度分析的概念一知半解,无需担心,后续章节会展开介绍。
## 2.1.3. 复杂度分析重要性
复杂度分析给出一把评价算法效率的“标尺”,告诉我们执行某个算法需要多少时间和空间资源,也让我们可以开展不同算法之间的效率对比。

View File

@@ -1289,8 +1289,8 @@ $$
if n <= 0 {
return 0
}
// 数组 nums 长度为 n, n-1, ..., 2, 1
nums := make([]int, n)
fmt.Printf("递归 n = %d 中的 nums 长度 = %d \n", n, len(nums))
return spaceQuadraticRecur(n - 1)
}
```

View File

@@ -80,6 +80,7 @@ comments: true
=== "Go"
```go title="leetcode_two_sum.go"
/* 方法一:暴力枚举 */
func twoSumBruteForce(nums []int, target int) []int {
size := len(nums)
// 两层循环,时间复杂度 O(n^2)
@@ -257,6 +258,7 @@ comments: true
=== "Go"
```go title="leetcode_two_sum.go"
/* 方法二:辅助哈希表 */
func twoSumHashTable(nums []int, target int) []int {
// 辅助哈希表,空间复杂度 O(n)
hashTable := map[int]int{}

View File

@@ -560,7 +560,7 @@ $T(n)$ 是个一次函数,说明时间增长趋势是线性的,因此易得
2. **省略所有系数**。例如,循环 $2n$ 次、$5n + 1$ 次、……,都可以化简记为 $n$ 次,因为 $n$ 前面的系数对时间复杂度也不产生影响。
3. **循环嵌套时使用乘法**。总操作数量等于外层循环和内层循环操作数量之积,每一层循环依然可以分别套用上述 `1.` 和 `2.` 技巧。
根据以下示例使用上述技巧前、后的统计结果分别为
以下示例展示了使用上述技巧前、后的统计结果
$$
\begin{aligned}
@@ -838,7 +838,7 @@ $$
count := 0
size := 100000
for i := 0; i < size; i++ {
count ++
count++
}
return count
}