算法刷题部分复习
参考资料:
代码随想录: https://programmercarl.com/
算法复杂度分析
时间复杂度
时间复杂度$O(1)<O(\log n)<O(n)<O(n \log n)<O(n^2)$.
对于算法的时间复杂度要学会分析,从而推断程序运行的时间。
空间复杂度
单个变量的空间复杂度是$O(1)$,一维数组的空间复杂度是$O(n)$,二维数组的空间复杂度即为$O(n^2)$。
递归算法的时间复杂度
算法复杂度=递归次数*递归操作次数
例1 求x的n次方:
给定$x$和$n$,求$f(x)=x^n$
解法1:
思路:当n=0的时候返回1,否则进入循环,用$res$记录结果,每次都乘上$x$。
1 |
|
此时的算法复杂度为$O(n)$。
解法2:
思路:用递归法,每次都求$f(x, n/2)$,避免重复的计算。
1 |
|
此时算法的复杂度是$O(\log n)$.
例2 求Fibonacci数列
问题:求Fibonacci数列,$f(0) = 0,f(1) = 1,f(n)=f(n-1)+f(n-2)$. 若$n<0$,则$f(n)=0$.
解法1:
思路:递归法,每次都递归地求$f(n-1)$和$f(n-2)$.
1 |
|
此时算法的时间复杂度为$O(2^n)$,空间复杂度为$O(n)$。
解法2:
思路:非递归法,每次分别用三个数字记录$f(n-2)$、$f(n-1)$和$f(n)$.
1 |
|
解法3:
递归法,但是每次都用数值代替递归的过程。
1 |
|
此时,算法的复杂度为$O(n)$.
内存管理
C++中的内存管理
C++中存在内存泄漏,主要是用户在new了对象后没有进行释放。
C++程序运行时,内存主要分为两个部分:固定部分和可变部分。
- 固定部分
- 代码
- 代码的二进制代码
- 数据
- 静态参数、常量和全局变量等
- 代码
- 可变部分
- 堆区
- 动态开辟的空间,存放new出来的对象在堆区中的真实数据,需要用户回收。
- 栈区
- 代码运行过程中的变量、递归栈所需的空间、形参、局部变量等。
- 堆区
Python中的内存管理
python中的万物皆对象,封装好了给用户。内存管理是由私有堆空间管理的,所有的python对象和数据结构都存储在私有堆空间中。程序员没有访问堆的权限,只有解释器才能操作。
Java中的内存管理
Java使用JVM进行内存管理。不了解jvm内存管理的机制,很可能会因一些错误的代码写法而导致内存泄漏或内存溢出。
内存对齐
内存对齐主要针对两个方面的问题:
① 平台。不是所有的硬件平台都能访问任意内存地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。为了同一个程序可以在多平台运行,需要内存对齐。
② 硬件。经过内存对齐后,CPU访问内存的速度大大提升。
1 | struct node{ |
该结构体的大小为8个字节(对齐后)。若不进行内存对齐,则会存在需要二次寻址、一次合并的需求。