算法的复杂度分析(一)


零. 写在前面

对于一个程序而言,最重要需要考虑的资源一个是运行时间,一个是占用空间的大小,两者直接关系到算法的性能与可行性,那么如何量化分析这两个维度呢,于是便引入了时间复杂度空间复杂度的概念。以下对两者做一些小结与思考。

时间复杂度分析:将算法中基本操作的执行次数(而非总时间)作为算法时间复杂度的度量。可以理解为:当数据规模扩大一倍时,算法的时间如何如何扩大。


一、时间复杂度

这里讨论虽然名为时间复杂度,但其实真正需要关心的是算法当中基本操作的总次数,因为实际运行的时间与硬件性能也有一定的相关性,因此衡量一个算法的性能要排除硬件的影响因而需要明确基本操作重复执行的次数即可。

因此时间复杂度可以量化为T(n) = O(算法操作数中增长最快的项/该项的系数) 。以简单的等差数列为例,见欧拉计划第一题,题目如下。
在这里插入图片描述
其中一种比较直接的算法是从1~1000遍历,判断这个数是不是3或5的倍数,如果是,便进行累加,核心代码如下:

int ans = 0;
for(int i = 1; i < 1000; i++){ 
	if(i % 3 == 0 || i % 5 == 0){ 
		ans += i; 
		}
	}
printf("%d\n", ans);

分析:
在整个遍历过程中,其总共经过了1+2n+n=3n+1次操作,因此T(n)=O(3n/3)=O(n),当数据规模扩大一倍时,总体上是以n的倍数线性扩大的。

当然,也可以利用等差数列求和的方式对该题目进行求解,核心代码如下:

int ans = 0;
int t3 = (3 + 999) * 333 / 2;
int t5 = (5 + 995) * 199 / 2;
int t15 = (15 + 990) * 66 / 2;
ans = t3 + t5 - t15;
printf("%d\n", ans);

分析:
不难看出,无论数据扩大多少,其所需要的计算的步骤只有4步,因此T(n) = O(4/4)=O(1),即使扩大的扩大的规模,所需要的操作数并不改变。

综上可以得出求解时间复杂度的两个步骤:
1)确定算法中的基本操作以及问题的规模
2)T(n)=O(算法操作数中增长最快的项/该项的系数)


二、关于时间复杂度的说明

一般而言,算法的数据量较大,而增长最快的项数前的系数并不大,因此一般满足以下的比较关系:

O(1) ≤ O( l o g 2 n log_{2}n log2n ) ≤ O(n) ≤ O(n * l o g 2 n log_{2}n log2n ) ≤ O(n²) ≤ …… ≤ O(nk) ≤ O(2n)

但该等式也并不绝对,应视具体情况而定,例如对于 O(4n) 与 O(n²) 当n=100时,显然前者的操作数要大于后者(在不考虑其他低阶项的情况下)。


PS:有的算法中的基本操作的执行次数不仅跟初始输入的数据规模有关,还和数据本身有关,例如,一些排序算法,同样有n个待处理数据,但数据的有序性不同,则基本操作的执行次数也不同,一般依照使得基本操作执行次数最多来计算时间复杂度,即将最坏的情况作为算法时间复杂度的衡量。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值