备战BAT面试:查漏补缺——如何计算复杂度

备战BAT面试的学习记录,整理了最近自己查漏补缺的知识点,总结出来和大家分享,如有错误,欢迎指出!

备战BAT面试


为什么需要复杂度分析?

因为可以脱离测试环境,硬件设备,数据规模等意外因素的干扰。

如何表示复杂度?

大O复杂度表示法:

int test(int n){
	int a = 0;
	int i= 1;
	for(; i<=n ; i++){
		a = a + i;
	}
	return a;
}

在上式中设每行代码执行时间为一个单位时间。那么第2、3行分别需要一个单位时间,所以需要2单位时间。而4、5行都运行了n遍,所以需要2n单位时间。总的需要(2n+2)*单位时间。
所以我们有一个公式:T(n)=O(f(n))
即所有代码执行时间与每行代码执行次数成正比。
例子中T(n)=O(2n+2),这就是大O时间复杂度表示法,也叫时间复杂度。
在记录时间复杂度时,我们只需要取最大的量级就行,因此T(n)=O(2n+2)可以记作O(n)。


下面通过几个例子来看:

O(1)

int test(){
	int a = 0;
	int i= 1;
	a = a + i;
	return a;
}

此时T(n)=O(3),但是我们可以用O(1)表示。因为O(1)表示常量级。

int test(){
	int a = 0;
	int i= 1;
	for(; i<=100 ; i++){
		a = a + i;
	}
	return a;
}

此时T(n)=O(102),也可以表示为O(1)。
所以说,只要没有随着n增长而时间变长的执行语句(最典型的就是没有n)那就是常量时间。

O(logn)

int test(int n){
	int a = 1;
	while(a<=n){
		a=a*2;
	}	
	return a;
}

可以看到退出条件为:当a乘了x个2之后等于n。也就是2^x=n,x=log2n。时间复杂度为O(logn)。这里可以说一下,无论log以什么为底数,都可以统一为logn。因为logan=logab x logbn。即logan=C x logbn。log2n、log3n、log100n之间只要成一个常数C就能转换,因此统一为logn。

O(m+n)

就是由两个变量决定

int test(int n,int m){
	int a = 0;
	int b = 0;
	int i= 1;
	int j= 1;
	for(; i<=n ; i++){
		a = a + i;
	}
	for(; j<=m ; j++){
		b = b + j;
	}
	return a+b;
}

此时为m和n共同决定,因此T(n)=O(m+n)。

O(n2)

int test(int n,int m){
	int a = 0;
	int i= 1;
	int j= 1;
	for(; i<=n ; i++){
		for(; j<=n ; j++){
			a = a + j;
		}
	}
	return a;
}

两个循环嵌套,里循环运行n2次,因此T(n)=O(n2)。
同理三个循环嵌套就是O(n3)。

你可能感兴趣的:(备战BAT面试)