系列文章目录
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用
前言
个人学习总结:
日常工作学习中,考量执行效率是算法的一个重要指标。分析时间、空间复杂度能让我们更了解如何让代码运行更快,如何让代码更省存储空间。
Q:平常可以通过统计、监控,就能得到算法执行时间与占用的内存大小,是否有必要自己分析时间、空间复杂度?
A:
1、通过统计、监控得到的测试结果会受到硬件环境的影响;
2、测试结果会受到数据规模的影响。
3、懂得分析复杂度之后,可以对写自己的代码有一定的认识,能够有意识的去优化改进代码。
一、时间(空间)复杂度介绍
时间(空间)复杂度的计算公式为:T(n) = O(f(n));
T(n):代码执行的时间;
n:数据规模的大小;
f(n):每行代码执行的次数总和(平常只关注量级最大的代码的次数,忽略低阶、常数、系数);
例如:f(n) = 2n^2 + 2n + 3,则时间复杂度为T(n) = O(n^2)。
常见的复杂度量级:
- 常数阶:O(1);
- 对数阶:O(logn);
- 线性阶:O(n);
- 线性对数阶:O(nlogn);
- k次方阶:O(n^k);
- 指数阶:O(2^n);
- 阶乘阶:O(n!);
二、最好、最坏、平均、均摊时间复杂度:
1.最好、最坏、平均时间复杂度
代码如下:
// n 表示数组 array 的长度
int find(int[] array, int n, int x)
{
int i = 0;
int pos = -1;
for (; i < n; ++i)
{
if (array[i] == x)
{
pos = i;
break;
}
}
return pos;
}
以上代码要实现的功能是,在一个无序的数组(array)中,查找变量x 出现的位置。如果没有找到,就返回 -1。
这段代码的如果没有"break;",那么其复杂度是 O(n),其中,n 代表数组的长度;
但是加了"break;",在不同情况下,它的时间复杂度是不一样的;例如第一个元素等于x,那么其时间复杂度为O(1);array中没有元素等于x,那么其时间复杂度为O(n)。针对不同情况,有三种概念表示:
- 最好情况时间复杂度:在最理想的情况下,执行这段代码的时间复杂度;比如上述描述的在第一个元素就找到所要的值。
- 最坏情况时间复杂度:在最糟糕的情况下,执行这段代码的时间复杂度;比如遍历完全部,都未找到所要的值。
- 平均情况时间复杂度:以上两种情况都是极端情况,其他大概率发生的情况的复杂度用平均时间复杂度来表示。计算方式为 n+1种情况所需要遍历的次数之和 / n+1种所有情况:
(1 + 2 + 3 + … + n + n) / (n + 1) = n*(n + 3) / 2*(n + 1);(第二个n为未找到x的遍历次数,所以共有n+1种情况);
去掉系数、常数、低阶后,计算得平均时间复杂度为T(n) = O(n)。
注:通常还需每种情况乘上其所出现的概率
2.均摊时间复杂度
均摊时间复杂度与平均时间复杂度类似,但有时计算平均复杂度还得考虑概率;
均摊简单来说就是将出现次数少的情况的时间复杂度平均分摊到出现次数多的情况的时间复杂度去。