复杂度分析(进阶版)

本文是学习算法的笔记,《数据结构与算法之美》,极客时间的课程

上篇文章说了时间复杂度的问题,这篇文章主要说几个概念
最好情况时间复杂度 (best case time complexity)
最坏情况时间复杂度(worst case time complexity)
平均情况时间复杂度(average case time complexity)
均摊时间复杂度(amortized time complexity)

// n 表示数据a 的长度
int find(int[] a , int n, int x){
	int pos = -1;
	int i = 0;
	for(; i<n; i++){
		if(a[i] = x){
			pox = i;
			break;
		}
	}
	return pos;
}

这段代码就是找出x 在数组a中的位置并返回,如果不在数组中则返回-1
如何分析这段代码的复杂度,假设x是数组的第一个元素,那么时间复杂度就是O(1),它就对应最好情况时间复杂度。如果x是数组的最后一个元素,那时间复杂度就是O(n),它就对应最坏时间复杂度。

那什么是平均情况时间复杂度呢?为了方便计算,元素x是数组内元素的概率为p, 等于每个元素的概率就是1/np,那么求出在数组里的加权平均数 1* 1/np + 2* 1/np +……+n * 1/np = (1+n)/2p,若在数组外,复杂度为 (n+1)*(1-p)。总的时间复杂度就是(n+1)*常数 即为0(n)

至于均摊时间复杂度,运用场景是很少的,有点复杂。前面的几个概念掌握基本就够用了。简单说下,看下面的伪代码。(只是为了说明这种情况,实际上,没人会这么写代码)

int[] array = new int[n];
int count = 0;
void insert(int val){
	if(count == array.length){
		int sum = 0;
		for(int i = 0; i < array.length : i++){
			sum = sum + array[i]
		}
		array[0] = sum;
		count = 1;
	}
}

解析下这段代码,往一个数组中插入数据,当数组有空闲的空间,就直接插入。若没有,就把求出数组元素的和,再清空数组,把这个和赋值给数组的第一个元素。

复杂度分析,最好情况,数组里有空间,直接插入,最好情况时间复杂度为O(1),最坏情况,数组没有空间了,需要做一次数组遍历之后求和,最坏情况时间复杂度为O(n)。平均情况时间复杂度,可有前面讲的概率的方法计算,是O(1)。

数组长度为n,就有n个位置可供插入,还有一种情况是数组插满了。总共(n+1)种情况,每种情况概率就是1/(n+1)。 就是n个1 * 1/(n+1)相加,然后再加上 n * 1/(n+1) 最后算出来就是O(1)。

这个insert()方法很特殊,很有规律,n 个时间复杂度为O(1)之后,紧跟着一个时间复杂度O(n),循环往复。这时,可引入简单的均摊时间复杂度来分析,可以不用复杂的加权平均数求平均情况时间复杂度。大概可以这么理解,把一个O(n)操作,均分到n个o(1)操作,总体上就得到o(1)。

一般来说,在可以用到均摊时间复杂度的地方,其值等于最好情况时间复杂度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值