1.1 时间复杂度
描述:总执行时间 与 基本执行时间的关系;
函数表达示例:T(n) = 5n;
渐进时间复杂度
为了更好的解决时间分析的问题,有了渐进时间复杂度;
官方定义如下:
若存在函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称为O(f(n)),O为算法的渐进时间复杂度,简称为时间复杂度
因为渐进时间复杂度用大写O来表示,所以也被称为大O表示法。
直白地讲,时间复杂度就是把程序的相对执行时间函数T(n)简化为一个数量级,这个数量级可以是n、n2、n3等。
如何推导出时间复杂度呢?有如下几个原则:
- 如果运行时间是常量级,则用常数1表示;
- 只保留时间函数中的高阶项;
- 如果高阶项存在,则省区高阶项前面的系数;
示例场景复杂度分析:
场景1:
T(n) = 3n,
最高阶项为3n, 剩去系数3,则转化的时间复杂度为:
T(n) = O(n);
场景2:
T(n)=5logn,
最高阶项为5logn,省去系数5,则转化的时间复杂度为:
T(n)=O(logn)。
场景3
T(n)=2,
只有常数量级,则转化的时间复杂度为:
T(n)=O(1)。
场景4
T(n)=0.5n2+0.5n,
最高阶项为0.5n2,省去系数0.5,则转化的时间复杂度为:
T(n)=O(n2)。
1.2 空间复杂度
运行一段程序过程中,临时存储的中间数据所占用的空间大小;
示例:
给出1列数据,其中有两个元素是重复的,找出重复的元素;
算法1:双重for循环,找出重复元素;
时间复杂度:O(n2);
空间复杂度:O(1);
算法2:将数据存入字典中,找出重复元素;
时间复杂度:O(n)
空间复杂度:O(n)
常见空间复杂度有下面几种情况;
1).常量空间
当算法的存储空间大小固定,和输入规模没有直接的关系时,空间复杂度记作O(1)。例如下面这段程序:
void fun1(int n){
i = 3;
// do something;
}
2).线性空间
当算法分配的空间是一个线性的集合(如列表),并且集合大小和输入规模n成正比时,空间复杂度记作O(n)。例如下面这段程序:
void fun2(int n){
int [] array = new int [n];
// do something;
}
3).二维空间
当算法分配的空间是一个二维列表集合,并且集合的长度和宽度都与输入规模n成正比时,空间复杂度记作O(n2)。例如下面这段程序:
void fun3(int n){
int [][] array = new int [n][n];
// do something;
}
4).递归空间
递归是一个比较特殊的场景。虽然递归代码中并没有显式地声明变量或集合,但是计算机在执行程序时,会专门分配一块内存,用来存储“函数调用栈”。
下面这段程序是一个标准的递归程序:
void fun4(int n){
if(n > 0){
fun4(n-1);
}
// do something;
}
空间复杂度就是O(n)
1.3 小结
啥是算法?
一系列程序指令的集合,处理特定的运算和逻辑问题;衡量算法优劣的主要标准是时间复杂度和空间复杂度;
啥是数据结构?
数据结构是数据的组织、管理和存储格式,目的是高效的访问和修改数据;
数据结构包含数组、链表这些线性结构;也包含树、图这样的复杂结构;
啥是时间复杂度?
对一个算法运行时间长度的度量;用大O标识,记作 T(n) = O(f(n)) ;
常见的时间复杂度按照从低到高的顺序,包括:O(1)、O(logn)、O(n)、O(nlogn)、O(n2)等;
啥是空间复杂度?
空间复杂度是对一个算法在运行过程中临时占用空间的度量;用大O表示,记作 S(n) = O(f(n));
常见的时间复杂度按照从低到高的顺序,包括O(1)、O(n)、O(n2)等,其中递归算法的空间复杂度和递归深度成正比;
参见
📚书籍--【漫画算法:小灰的算法之旅(Python篇)】