常见的时间复杂度
常见时间复杂度的比较
当算法的时间复杂度为 O(2n)(n为指数),O(n!),或O(nn)(n为指数)时,即使n的值很小,实际的程序运行时间也是不可接收的。
算法的最好与最坏情况
意义:当算法在最坏情况下仍然能满足需求时,可以推断,算法的最好情况和平均情况都能满足需求。
算法分析示例
int find(int a[], int n, int v)
{
int ret = -1;
for (int i=0; i<n; ++i)
{
if (a[i] == v)
{
ret = i;
break;
}
}
return ret;
}
int main()
{
int arr[5] = {1,2,3,4,5};
int min = find(arr, 5, 1); // 最好情况,执行1次循环,O(1)
int max = find(arr, 5, 5); // 最坏情况,执行n次循环,O(n)
}
注意:数据结构课程中,在没有特殊说明时,所分析算法的时间复杂度都是指最坏时间复杂度。
算法的空间复杂度(Space Complexity)
定义: S(n) = S(f(n))
- n 为算法的问题规模
- f(n) 为空间使用函数,与n相关
推导时间复杂度的方法同样适用于空间复杂度。
例如:
当算法所需要的空间是常数时,空间复杂度为S(1)
空间复杂度计算练习
long sum1(int n) // 1
{
long ret = 0; // 1
int *array = new int[n]; // n
for (int i=0; i<n; ++i) // 1
{
array[i] = i + 1;
}
for (int i=0; i<n; ++i) // 1
{
ret += array[i];
}
delete[] array;
return ret;
}
所需的单元内存: n + 4
空间复杂度:S(n+4) = S(n)
空间与时间的策略
- 多数情况下,算法的时间复杂度更令人关注
- 如果有必要,可以通过增加额外空间降低时间复杂度
- 同理,可以通过增加算法的耗时降低空间复杂度
以上策略的依据:当前硬件的发展速度超过了软件的发展速度
实例分析:空间换时间
/*
问题:
在一个由自然数1-1000中某些数字所组成的数组中,每个数字可能出现零次或者多次。
设计一个算法,找出出现次数最多的数字。
*/
#include <iostream>
using namespace std;
void search(int a[], int len) // O(n)
{
int sp[1000] = {0};
int max = 0;
for(int i=0; i<len; i++)
{
sp[a[i] - 1]++;
}
for(int i=0; i<1000; i++)
{
if( max < sp[i] )
{
max = sp[i];
}
}
for(int i=0; i<1000; i++)
{
if( max == sp[i] )
{
cout << i + 1 << endl;
}
}
}
int main(int argc, char* argv[])
{
int a[] = {1, 1, 3, 4, 5, 6, 6, 6, 3, 3};
search(a, sizeof(a)/sizeof(*a));
return 0;
}
输出:
3
6
面试题
当两个算法的大O表示法相同时,是否意味着两个算法的效率完全相同?
答:只能说效率同等级别,不能说完全相同。因为大O表示法只关注操作数量的最高次项。
小结
- 一般而言,工程中使用的算法,时间复杂度不超过O(n3)(3为指数)
- 算法分析与设计时,重点考虑最坏情况下的时间复杂度
- 数据结构课程终重点关注算法的时间复杂度
- 大O表示法同样适用于空间复杂度
空间换时间是工程中常用的策略
以上内容整理于狄泰软件学院系列课程,请大家保护原创!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。