Skip to content

Commit 87c5b40

Browse files
committed
Add Time_Complexity
1 parent 9a30c00 commit 87c5b40

File tree

4 files changed

+151
-10
lines changed

4 files changed

+151
-10
lines changed

ctl/label.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,19 @@ import (
44
"bufio"
55
"errors"
66
"fmt"
7-
"github.com/halfrost/LeetCode-Go/ctl/util"
8-
"github.com/spf13/cobra"
97
"io"
108
"io/ioutil"
119
"os"
1210
"regexp"
1311
"strings"
12+
13+
"github.com/halfrost/LeetCode-Go/ctl/util"
14+
"github.com/spf13/cobra"
1415
)
1516

1617
var (
17-
chapterOneFileOrder = []string{"_index", "Data_Structure", "Algorithm"}
18-
chapterOneMenuOrder = []string{"_index", "#关于作者", "Data_Structure", "Algorithm"}
18+
chapterOneFileOrder = []string{"_index", "Data_Structure", "Algorithm", "Time_Complexity"}
19+
chapterOneMenuOrder = []string{"_index", "#关于作者", "Data_Structure", "Algorithm", "Time_Complexity"}
1920
chapterTwoFileOrder = []string{"_index", "Array", "String", "Two_Pointers", "Linked_List", "Stack", "Tree", "Dynamic_Programming", "Backtracking", "Depth_First_Search", "Breadth_First_Search",
2021
"Binary_Search", "Math", "Hash_Table", "Sort", "Bit_Manipulation", "Union_Find", "Sliding_Window", "Segment_Tree", "Binary_Indexed_Tree"}
2122
chapterThreeFileOrder = []string{"_index", "Segment_Tree", "UnionFind", "LRUCache", "LFUCache"}
@@ -34,10 +35,10 @@ var (
3435

3536
chapterMap = map[string]map[string]string{
3637
"ChapterOne": {
37-
"_index": "第一章 序章",
38-
"#关于作者": "1.1 关于作者",
39-
"Data_Structure": "1.2 数据结构知识",
40-
"Algorithm": "1.3 算法知识",
38+
"_index": "第一章 序章",
39+
"Data_Structure": "1.1 数据结构知识",
40+
"Algorithm": "1.2 算法知识",
41+
"Time_Complexity": "1.3 时间复杂度",
4142
},
4243
"ChapterTwo": {
4344
"_index": "第二章 算法专题",

website/content/ChapterOne/Algorithm.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ weight: 2
3030
----------------------------------------------
3131
<div style="display: flex;justify-content: space-between;align-items: center;">
3232
<p><a href="https://books.halfrost.com/leetcode/ChapterOne/Data_Structure/">⬅️上一页</a></p>
33-
<p><a href="https://books.halfrost.com/leetcode/ChapterTwo/">下一章➡️</a></p>
33+
<p><a href="https://books.halfrost.com/leetcode/ChapterOne/Time_Complexity/">下一页➡️</a></p>
3434
</div>
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
---
2+
title: 1.3 时间复杂度
3+
type: docs
4+
weight: 3
5+
---
6+
7+
# 时间复杂度和空间复杂度
8+
9+
10+
## 一. 时间复杂度数据规模
11+
12+
1s 内能解决问题的数据规模:10^6 ~ 10^7
13+
14+
- O(n^2) 算法可以处理 10^4 级别的数据规模(保守估计,处理 1000 级别的问题肯定没问题)
15+
- O(n) 算法可以处理 10^8 级别的数据规模(保守估计,处理 10^7 级别的问题肯定没问题)
16+
- O(nlog n) 算法可以处理 10^7 级别的数据规模(保守估计,处理 10^6 级别的问题肯定没问题)
17+
18+
| | 数据规模|时间复杂度 | 算法举例|
19+
|:------:|:------:|:------:|:------:|
20+
|1|10|O(n!)|permutation 排列|
21+
|2|20~30|O(2^n)|combination 组合|
22+
|3|50|O(n^4)|DFS 搜索、DP 动态规划|
23+
|4|100|O(n^3)|任意两点最短路径、DP 动态规划|
24+
|5|1000|O(n^2)|稠密图、DP 动态规划|
25+
|6|10^6|O(nlog n)|排序,堆,递归与分治|
26+
|7|10^7|O(n)|DP 动态规划、图遍历、拓扑排序、树遍历|
27+
|8|10^9|O(sqrt(n))|筛素数、求平方根|
28+
|9|10^10|O(log n)|二分搜索|
29+
|10|+∞|O(1)|数学相关算法|
30+
|----------------|----------------|------------------------------------------------------------------|--------------------------------|
31+
32+
33+
一些具有迷惑性的例子:
34+
35+
```c
36+
void hello (int n){
37+
38+
for( int sz = 1 ; sz < n ; sz += sz)
39+
for( int i = 1 ; i < n ; i ++)
40+
cout << "Hello" << endl;
41+
}
42+
```
43+
44+
上面这段代码的时间复杂度是 O(nlog n) 而不是 O(n^2)
45+
46+
```c
47+
bool isPrime (int n){
48+
49+
for( int x = 2 ; x * x <= n ; x ++ )
50+
if( n % x == 0)
51+
return false;
52+
return true;
53+
}
54+
```
55+
56+
上面这段代码的时间复杂度是 O(sqrt(n)) 而不是 O(n)。
57+
58+
再举一个例子,有一个字符串数组,将数组中的每一个字符串按照字母序排序,之后再降整个字符串数组按照字典序排序。两步操作的整体时间复杂度是多少呢?
59+
60+
如果回答是 O(n*nlog n + nlog n) = O(n^2log n),这个答案是错误的。字符串的长度和数组的长度是没有关系的,所以这两个变量应该单独计算。假设最长的字符串长度为 s,数组中有 n 个字符串。对每个字符串排序的时间复杂度是 O(slog s),将数组中每个字符串都按照字母序排序的时间复杂度是 O(n * slog s)。
61+
62+
将整个字符串数组按照字典序排序的时间复杂度是 O(s * nlog n)。排序算法中的 O(nlog n) 是比较的次数,由于比较的是整型数字,所以每次比较是 O(1)。但是字符串按照字典序比较,时间复杂度是 O(s)。所以字符串数组按照字典序排序的时间复杂度是 O(s * nlog n)。所以整体复杂度是 O(n * slog s) + O(s * nlog n) = O(n\*slog s + s\*nlogn) = O(n\*s\*(log s + log n))
63+
64+
## 二. 空间复杂度
65+
66+
递归调用是有空间代价的,递归算法需要保存递归栈信息,所以花费的空间复杂度会比非递归算法要高。
67+
68+
```c
69+
int sum( int n ){
70+
assert( n >= 0 )
71+
int ret = 0;
72+
for ( int i = 0 ; i <= n ; i++)
73+
ret += i;
74+
return ret;
75+
}
76+
```
77+
78+
上面算法的时间复杂度为 O(n),空间复杂度 O(1)。
79+
80+
```c
81+
int sum( int n ){
82+
assert( n >= 0 )
83+
if ( n == 0 )
84+
return 0;
85+
return n + sum( n - 1);
86+
}
87+
```
88+
89+
上面算法的时间复杂度为 O(n),空间复杂度 O(n)。
90+
91+
## 三. 递归的时间复杂度
92+
93+
### 只有一次递归调用
94+
95+
如果递归函数中,只进行了一次递归调用,且递归深度为 depth,在每个递归函数中,时间复杂度为 T,那么总体的时间复杂度为 O(T * depth)
96+
97+
举个例子:
98+
99+
```c
100+
int binarySearch(int arr[], int l, int r, int target){
101+
if( l > r)
102+
return -1;
103+
int mid = l + (r-l)/2;//防溢出
104+
if(arr[mid] == target)
105+
return mid;
106+
else if (arr[mid]>target)
107+
return binarySearch(arr,l,mid-1,target);
108+
eles
109+
return binarySearch(arr,mid+1,r,target);
110+
}
111+
112+
```
113+
114+
在二分查找的递归实现中,只递归调用了自身。递归深度是 log n ,每次递归里面的复杂度是 O(1) 的,所以二分查找的递归实现的时间复杂度为 O(log n) 的。
115+
116+
117+
### 只有多次递归调用
118+
119+
针对多次递归调用的情况,就需要看它的计算调用的次数了。通常可以画一颗递归树来看。举例:
120+
121+
```c
122+
int f(int n){
123+
assert( n >= 0 );
124+
if( n ==0 )
125+
return 1;
126+
return f( n - 1 ) + f ( n - 1 );
127+
128+
```
129+
130+
上述这次递归调用的次数为 2^0^ + 2^1^ + 2^2^ + …… + 2^n^ = 2^n+1^ - 1 = O(2^n)
131+
132+
133+
> 关于更加复杂的递归的复杂度分析,请参考,主定理。主定理中针对各种复杂情况都给出了正确的结论。
134+
135+
136+
----------------------------------------------
137+
<div style="display: flex;justify-content: space-between;align-items: center;">
138+
<p><a href="https://books.halfrost.com/leetcode/ChapterOne/Algorithm/">⬅️上一页</a></p>
139+
<p><a href="https://books.halfrost.com/leetcode/ChapterTwo/">下一章➡️</a></p>
140+
</div>

website/content/ChapterTwo/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ weight: 2
2424

2525
----------------------------------------------
2626
<div style="display: flex;justify-content: space-between;align-items: center;">
27-
<p><a href="https://books.halfrost.com/leetcode/ChapterOne/Algorithm/">⬅️上一章</a></p>
27+
<p><a href="https://books.halfrost.com/leetcode/ChapterOne/Time_Complexity/">⬅️上一章</a></p>
2828
<p><a href="https://books.halfrost.com/leetcode/ChapterTwo/Array/">下一页➡️</a></p>
2929
</div>

0 commit comments

Comments
 (0)