面试题目:时间复杂度

一,定义

时间复杂度:就是说执行算法需要消耗的时间长短,越快越好。在一个算法存在最好、平均、最坏三种情况,我们一般关注的是最坏情况,原因是最坏情况是任何输入实例在运行时间的上界。

二,表示方法

一般用"大O符号表示法"来表示时间复杂度:T(n)=O(f(n)),n是影响复杂度变化的因子,f(n)是复杂度具体的算法。

三,如何推导出时间复杂度呢

1,如果运行时间是常数量级,用常数1表示;

2,只保留时间函数中的最高阶项;

3,如果最高阶项存在,则省去最高阶项前面的系数

三,常见的时间复杂度量级

3.1,常数阶O(1)

int a = 1;
int b = 2;
int c = 3;

我们假定每执行一行代码所需要消耗的时间为1个时间单位,那么以上3行代码就消耗了3个时间单位,那是不是这段代码的时间复杂度为O(n)呢 ?其实不是的,因为大O符号表示法并不是用来表示算法的执行时间,它是用来表示代码执行时间的增长变化趋势。

3.2,线性阶O(n)

for(i = 1; i <= n; i++) {
   j = i;
   j++;
}

第1行会执行1次,第2行和第3行会分别执行n次,总的执行时间也就是 2n + 1 次,那它的时间复杂度表示是 O(2n + 1) 吗? No !
还是那句话:“大O符号表示法并不是用于来真实代表算法的执行时间的,它是用来表示代码执行时间的增长变化趋势的”。
所以它的时间复杂度其实是O(n);原则:只保留时间函数中的最高阶项;如果最高阶项存在,则省去最高阶项前面的系数。

3.3,对数阶O(logN)

int i = 1;
while(i < n) {
    i = i * 2;
}
//或:
for(int i = 1; i < n; i = i*2){
    printf("i = %d",i);
}

可以看到每次循环的时候 i 都会乘2,那么总共循环的次数就是log2n,因此这个代码的时间复杂度为O(logn)。
这儿有个问题,为什么明明应该是O(log2n),却要写成O(logn)呢?
其实这里的底数对于研究程序运行效率不重要,写代码时要考虑的是数据规模n对程序运行效率的影响,常数部分则忽略,同样的,如果不同时间复杂度的倍数关系为常数,那也可以近似认为两者为同一量级的时间复杂度。

640?wx_fmt=png

3.4,线性对数阶O(nlogN)

for(m = 1; m < n; m++) {
    i = 1;
    while(i < n) {
        i = i * 2;
    }
}

线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)。

3.5,平方阶O(n²)

for(x = 1; i <= n; x++){
   for(i = 1; i <= n; i++) {
       j = i;
       j++;
    }
}

把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n²) 了。

3.6,立方阶O(n³),K次方阶O(n^k)

参考上面的O(n²) 去理解就好了,O(n³)相当于三层n循环,其它的类似。

3.8,指数阶(2^n)

640?wx_fmt=png

四,常见算法对应时间复杂度

二分法查找,二叉树遍历,最优排序矩阵搜索,归并排序

面试题目:时间复杂度_第1张图片

欢迎订阅公众号【从零开始学无线】,一起学习交流!

 

你可能感兴趣的:(嵌入式开发面试题目)