更新图床

This commit is contained in:
programmercarl
2023-03-10 14:02:32 +08:00
parent 2a9b627a90
commit 17cb4b45c7
134 changed files with 1169 additions and 829 deletions

View File

@ -8,7 +8,7 @@
## 超时是怎么回事
![程序超时](https://img-blog.csdnimg.cn/20200729112716117.png)
![程序超时](https://code-thinking-1253855093.file.myqcloud.com/pics/20200729112716117-20230310124308704.png)
大家在leetcode上练习算法的时候应该都遇到过一种错误是“超时”。
@ -48,6 +48,7 @@
尽管有很多因素影响,但是还是可以对自己程序的运行时间有一个大体的评估的。
引用算法4里面的一段话
* 火箭科学家需要大致知道一枚试射火箭的着陆点是在大海里还是在城市中;
* 医学研究者需要知道一次药物测试是会杀死还是会治愈实验对象;
@ -99,6 +100,7 @@ void function3(long long n) {
```
来看一下这三个函数随着n的规模变化耗时会产生多大的变化先测function1 ,就把 function2 和 function3 注释掉
```CPP
int main() {
long long n; // 数据规模
@ -122,11 +124,11 @@ int main() {
来看一下运行的效果,如下图:
![程序超时2](https://img-blog.csdnimg.cn/20200729200018460.png)
![程序超时2](https://code-thinking-1253855093.file.myqcloud.com/pics/20200729200018460-20230310124315093.png)
O(n)的算法1s内大概计算机可以运行 5 * (10^8)次计算,可以推测一下$O(n^2)$ 的算法应该1s可以处理的数量级的规模是 5 * (10^8)开根号,实验数据如下。
![程序超时3](https://img-blog.csdnimg.cn/2020072919590970.png)
![程序超时3](https://code-thinking-1253855093.file.myqcloud.com/pics/2020072919590970-20230310124318532.png)
O(n^2)的算法1s内大概计算机可以运行 22500次计算验证了刚刚的推测。
@ -134,7 +136,7 @@ O(n^2)的算法1s内大概计算机可以运行 22500次计算验证了刚
理论上应该是比 $O(n)$少一个数量级,因为$\log n$的复杂度 其实是很快,看一下实验数据。
![程序超时4](https://img-blog.csdnimg.cn/20200729195729407.png)
![程序超时4](https://code-thinking-1253855093.file.myqcloud.com/pics/20200729195729407-20230310124322232.png)
$O(n\log n)$的算法1s内大概计算机可以运行 2 * (10^7)次计算,符合预期。
@ -142,7 +144,7 @@ $O(n\log n)$的算法1s内大概计算机可以运行 2 * (10^7)次计算,
**整体测试数据整理如下:**
![程序超时1](https://img-blog.csdnimg.cn/20201208231559175.png)
![程序超时1](https://code-thinking-1253855093.file.myqcloud.com/pics/20201208231559175-20230310124325152.png)
至于 $O(\log n)$ 和 $O(n^3)$ 等等这些时间复杂度在1s内可以处理的多大的数据规模大家可以自己写一写代码去测一下了。
@ -204,6 +206,7 @@ int main() {
Java版本
```Java
import java.util.Scanner;
@ -274,4 +277,5 @@ public class TimeComplexity {
-----------------------
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码.jpg width=450> </img></div>

View File

@ -57,7 +57,7 @@
我做了一下总结如图:
![编程风格](https://img-blog.csdnimg.cn/20201119173039835.png)
![编程风格](https://code-thinking-1253855093.file.myqcloud.com/pics/20201119173039835.png)
### 水平留白(代码空格)

View File

@ -38,7 +38,7 @@
同样的同理再看一下快速排序都知道快速排序是O(nlogn)但是当数据已经有序情况下快速排序的时间复杂度是O(n^2) 的,**所以严格从大O的定义来讲快速排序的时间复杂度应该是O(n^2)**。
**但是我们依然说快速排序是O(nlogn)的时间复杂度这个就是业内的一个默认规定这里说的O代表的就是一般情况而不是严格的上界**。如图所示:
![时间复杂度4一般情况下的时间复杂度](https://img-blog.csdnimg.cn/20200728185745611.png)
![时间复杂度4一般情况下的时间复杂度](https://code-thinking-1253855093.file.myqcloud.com/pics/20200728185745611-20230310123844306.png)
我们主要关心的还是一般情况下的数据形式。
@ -49,7 +49,7 @@
如下图中可以看出不同算法的时间复杂度在不同数据输入规模下的差异。
![时间复杂度,不同数据规模的差异](https://img-blog.csdnimg.cn/20200728191447384.png)
![时间复杂度,不同数据规模的差异](https://code-thinking-1253855093.file.myqcloud.com/pics/20200728191447384-20230310124015324.png)
在决定使用哪些算法的时候不是时间复杂越低的越好因为简化后的时间复杂度忽略了常数项等等要考虑数据规模如果数据规模很小甚至可以用O(n^2)的算法比O(n)的更合适(在有常数项的时候)。
@ -115,7 +115,7 @@ O(2 × n^2 + 10 × n + 1000) < O(3 × n^2),所以说最后省略掉常数项
为什么可以这么做呢如下图所示
![时间复杂度1.png](https://img-blog.csdnimg.cn/20200728191447349.png)
![时间复杂度1.png](https://code-thinking-1253855093.file.myqcloud.com/pics/20200728191447349-20230310124032001.png)
假如有两个算法的时间复杂度分别是log以2为底n的对数和log以10为底n的对数那么这里如果还记得高中数学的话应该不难理解`以2为底n的对数 = 以2为底10的对数 * 以10为底n的对数`

View File

@ -1,5 +1,4 @@
# 刷了这么多题,你了解自己代码的内存消耗么?
理解代码的内存消耗,最关键是要知道自己所用编程语言的内存管理。
@ -20,7 +19,7 @@
如果我们写C++的程序,就要知道栈和堆的概念,程序运行时所需的内存空间分为 固定部分,和可变部分,如下:
![C++内存空间](https://img-blog.csdnimg.cn/20210309165950660.png)
![C++内存空间](https://code-thinking-1253855093.file.myqcloud.com/pics/20210309165950660.png)
固定部分的内存消耗 是不会随着代码运行产生变化的, 可变部分则是会产生变化的
@ -42,7 +41,7 @@
想要算出自己程序会占用多少内存就一定要了解自己定义的数据类型的大小,如下:
![C++数据类型的大小](https://img-blog.csdnimg.cn/20200804193045440.png)
![C++数据类型的大小](https://code-thinking-1253855093.file.myqcloud.com/pics/20200804193045440.png)
注意图中有两个不一样的地方为什么64位的指针就占用了8个字节而32位的指针占用4个字节呢
@ -85,9 +84,11 @@ int main() {
cout << sizeof(st) << endl;
}
```
看一下和自己想的结果一样么, 我们来逐一分析一下。
其输出的结果依次为:
```
4
1
@ -108,7 +109,7 @@ CPU读取内存不是一次读取单个字节而是一块一块的来读取
第一种就是内存对齐的情况,如图:
![内存对齐](https://img-blog.csdnimg.cn/20200804193307347.png)
![内存对齐](https://code-thinking-1253855093.file.myqcloud.com/pics/20200804193307347.png)
一字节的char占用了四个字节空了三个字节的内存地址int数据从地址4开始。
@ -116,7 +117,7 @@ CPU读取内存不是一次读取单个字节而是一块一块的来读取
第二种是没有内存对齐的情况如图:
![非内存对齐](https://img-blog.csdnimg.cn/20200804193353926.png)
![非内存对齐](https://code-thinking-1253855093.file.myqcloud.com/pics/20200804193353926.png)
char型的数据和int型的数据挨在一起该int数据从地址1开始那么CPU想要读这个数据的话来看看需要几步操作
@ -143,4 +144,5 @@ char型的数据和int型的数据挨在一起该int数据从地址1开始
-----------------------
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码.jpg width=450> </img></div>

View File

@ -103,7 +103,7 @@ Carl校招社招都拿过大厂的offer同时也看过很多应聘者的简
最后福利,把我的简历模板贡献出来!如下图所示。
![简历模板](https://img-blog.csdnimg.cn/20200803175538158.png)
![简历模板](https://code-thinking-1253855093.file.myqcloud.com/pics/20200803175538158.png)
这里是简历模板中Markdown的代码[https://github.com/youngyangyang04/Markdown-Resume-Template](https://github.com/youngyangyang04/Markdown-Resume-Template) 可以fork到自己Github仓库上按照这个模板来修改自己的简历。

View File

@ -28,7 +28,8 @@ int fibonacci(int i) {
可以看出上面的代码每次递归都是O(1)的操作。再来看递归了多少次这里将i为5作为输入的递归过程 抽象成一棵递归树,如图:
![递归空间复杂度分析](https://img-blog.csdnimg.cn/20210305093200104.png)
![递归空间复杂度分析](https://code-thinking-1253855093.file.myqcloud.com/pics/20210305093200104.png)
从图中可以看出f(5)是由f(4)和f(3)相加而来那么f(4)是由f(3)和f(2)相加而来 以此类推。
@ -194,7 +195,8 @@ int main()
在看递归的深度是多少呢?如图所示:
![递归空间复杂度分析](https://img-blog.csdnimg.cn/20210305094749554.png)
![递归空间复杂度分析](https://code-thinking-1253855093.file.myqcloud.com/pics/20210305094749554.png)
递归第n个斐波那契数的话递归调用栈的深度就是n。
@ -211,7 +213,8 @@ int fibonacci(int i) {
最后对各种求斐波那契数列方法的性能做一下分析,如题:
![递归的空间复杂度分析](https://img-blog.csdnimg.cn/20210305095227356.png)
![递归的空间复杂度分析](https://code-thinking-1253855093.file.myqcloud.com/pics/20210305095227356.png)
可以看出,求斐波那契数的时候,使用递归算法并不一定是在性能上是最优的,但递归确实简化的代码层面的复杂度。

View File

@ -69,7 +69,7 @@ int function3(int x, int n) {
我们来分析一下首先看递归了多少次呢可以把递归抽象出一棵满二叉树。刚刚同学写的这个算法可以用一棵满二叉树来表示为了方便表示选择n为偶数16如图
![递归算法的时间复杂度](https://img-blog.csdnimg.cn/20201209193909426.png)
![递归算法的时间复杂度](https://code-thinking-1253855093.file.myqcloud.com/pics/20201209193909426.png)
当前这棵二叉树就是求x的n次方n为16的情况n为16的时候进行了多少次乘法运算呢
@ -79,7 +79,7 @@ int function3(int x, int n) {
这么如果是求x的n次方这个递归树有多少个节点呢如下图所示(m为深度从0开始)
![递归求时间复杂度](https://img-blog.csdnimg.cn/20200728195531892.png)
![递归求时间复杂度](https://code-thinking-1253855093.file.myqcloud.com/pics/20200728195531892.png)
**时间复杂度忽略掉常数项`-1`之后这个递归算法的时间复杂度依然是O(n)**。对你没看错依然是O(n)的时间复杂度!