备战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)。