时间复杂度
执行算法的时间成本
场景1:T(n) = 3,当执行次数为线性
void eat1(int i){
for(int i = 0; i < n; i++){
System.out.print(“等待一分钟”);
System.out.print(“等待一分钟”);
System.out.print(“程序开始执行”);
}
}
场景2:T(n) = 5logn,当执行次数为对数
void eat2(int i){
for(int i = 0; i > 1; i/=2){
System.out.print(“等待一分钟”);
System.out.print(“等待一分钟”);
System.out.print(“等待一分钟”);
System.out.print(“等待一分钟”);
System.out.print(“每次计算除以2”);
}
}
场景3:T(n) = 2,当执行次数为常量
void eat3(int i){
System.out.print(“等待一分钟”);
System.out.print(“程序执行”);
}
场景4:T(n) = 0.5n^2 + 0.5n,执行次数为多项式
void eat4(int i){
for(int i = 0; i < n; i++){
for(int j = 0; j < i; j++){
System.out.print(“等待一分钟”);
}
System.out.print(“程序执行”);
}
}
以上四个场景可以称为基本操作所执行次数的函数T(n),当然只获取到了执行次数的函数T(n)是无法看出来时间复杂度是干什么的。所以官方定义了渐进时间复杂度,概念如下:若存在函数f(n),使得当n趋近于无穷大时,T(n)|f(n)的极限值为不等于零的一个常数,则称f(n)是T(n)的同数量级函数。记作T(n) = O(f(n)),称为O(f(n)),O为算法的渐进时间复杂度,简称为时间复杂度。 简述的讲就是时间复杂度把程序的相对执行时间函数f(n)简化为一个数量级,这个数量级可以为n,n2,n3等。
那么如何推算出时间复杂度呢?有以下几个原则。
1. 如果运行时间是常数量级,则可以用常数1表示。
2. 只保留时间函数中的最高阶项。
3. 若最高阶项存在,则省去最高阶项前面的系数。
我们可回头看前面四个场景
场景一:T(n) = 3n。
省去系数3,则可转化为T(n) = O(n)
场景二:T(n) = 5logn。
省去系数5,则可转化为T(n) = O(logn)
场景三:T(n) = 2。
常数量级,则可转化为T(n) = O(1)
场景四:T(n) = 0.5n^2 + 0.5n
省去系数0.5,则可转化为T(n) = O(n^2)
四种时间复杂度执行时长分别为:O(1) < O(logn) < O(n) < O(n2)
空间复杂度
执行算法的空间成本
- 常量空间
算法的存储空间大小固定,和输入规模没有直接的关系时,空间复杂度记作O(1)。
void fun1(int n){
int var = 3
...
}
- 线性空间
算法分配的空间如果是一个线性的集合(如数组),且集合大小和输入规模n成正比时,空间复杂度可记作O(n)。
void fun1(int n){
int[] array = new int[n];
...
}
- 二维空间
算法分配的空间是一个二维数组集合,且集合的长度和宽度都与输入规模n成正比时,空间复杂度记作O(n^2)。
void fun3(int n){
int[][] matrix = new int[n][n];
...
}
- 递归空间
递归算一个特殊的场景。会专门分配一块内存,用于存储"方法调用栈"。方法调用栈包括”进栈“和”出栈“两个行为。执行递归操作所需要的内存空间和递归的深度成正比。纯粹的递归操作的空间复杂度也是线性的,如果递归的深度是n,那么空间复杂度就是O(n);
void fun4(int n){
if(n<=1){
return;
}
fun4(n-1)
...
}
小结
1. 什么是算法
在计算机领域中,算法是一系列程序指令,可用于处理特定的运算和逻辑问题。衡量算法优劣的主要标准就是时间复杂度和空间复杂度。
2. 什么是数据结构
数据结构是数组的组织、管理和存储格式,其使用目的是为了高效地访问和修改数据。
数据结构包含数组、链表这样的线性数据结构,也包括树、图这样的复杂数据结构。
3. 什么是时间复杂度
时间复杂度是对一个算法运行时间长短的量度,用大O表示,记作T(n) = O(f(n))。
常见的时间复杂度按照从低到高顺序,包括了O(1),O(logn),O(n),O(nlogn),O(n^2)等。
4. 什么是空间复杂度
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度,用大O表示,记作Sn = O(f(n))。
常见的空间复杂度按照从低到高的顺序,包括O(1)、O(n)、O(n^2)等。其中递归算法的空间复杂度与递归深度是成正比的。
漫画算法:小灰的算法之旅