算法分析初步

来源:互联网 发布:淘宝店铺怎么开通直播 编辑:程序博客网 时间:2024/06/10 20:04

算法分析

201659

1:15

主要包括对时空复杂度的分析,还有算法的实际运行性能及算法可视化。

 

步骤:

1.量化算法的实际运行性能

   选择衡量算法实际性能的量化指标是他的实际运行时间。这与算法要解决的问题规模有关。

/*

大O符号是一种算法复杂度的相对表示方式。

  复杂度complexity,就是操作的数量)。

 我们称这为O(n)或者线性复杂度(linear complexity)

 

        我们只关心复杂度最重要的部分,,对于占操作总量很小比例的可以忽略,当我们做6位数乘法时,如果其中一个是4位数另一个是6位数,那么我们只需做24次乘法操作。然而,对于那个’n’,我们仍然计算最坏情况,即乘数都是6位数的情况。因此,大O符号是关于一个算法的最坏情况的。

 

例子:O(n^2) ---平方复杂度

 O(log n)---对数复杂度 :可以是任意底数,无关紧要

 O(1)---常数复杂度

 

电话簿搜索---二分搜索

对于算法,大O符号能够被用于决定3种情况:

  • 最好情况(Best Case):在电话簿的搜索中,最好情况是我们比较了1次就找到了名字。这就是O(1),即常数复杂度(constant complexity)
  • 期望情况(Expected Case):正如上面讨论过的,复杂度是O(log n);
  • 最坏情况(Worst Case):也是O(log n)。

 

旅行商问题的大O符号表示是O(n!),即阶乘(factorial)或组合复杂度(combinatorial complexity)

任何复杂度为O(na)的算法被称为有多项式复杂度(polynomial complexity),或可以在多项式时间(polynomial time)内解决。

*/

 

算法的运行时间究竟取决于什么,然而在实际的分析中,我们应该做的是集中注意力于最耗时的部分

,对那些耗时大但只执行常数次的操作我们可以忽略

 

我们知道分析算法的时间复杂度只需要两步(比把大象放进冰箱还少一步:)):

  • 寻找执行次数多的语句作为决定运行时间的[关键操作];
  • 分析关键操作的执行次数。

 

 

例题:

1.

【腾讯】下面算法的时间复杂度是____

int foo(int n) {

    if (n <= 1) {

        return 1

    }

    return n * foo(n - 1);

}

    看到这道题要我们分析算法时间复杂度后,我们要做的第一步便是确定关键操作,这里的关键操作显然是if语句,那么我们只需要判断if语句执行的次数即可。首先我们看到这是一个递归过程:foo会不断的调用自身,直到foo的实参小于等于1foo就会返回1,之后便不会再执行if语句了。由此我们可以知道,if语句调用的次数为n次,所以时间复杂度为O(n)

2.

【京东】以下函数的时间复杂度为____

void recursive(int n, int m, int o) {

    if (n <= 0) {

        printf("%d, %d\n", m, o);

    } else {

        recursive(n - 1, m + 1, o);

        recursive(n - 1, m, o + 1);

    }

}

    这道题明显要比上道题难一些,那么让我们来按部就班的解决它。首先,它的关键操作时if语句,因此我们只需判断出if语句的执行次数即可。以上函数会在n > 0的时候不断递归调用自身,我们要做的是判断在到达递归的base case(即n <= 0)前,共执行了多少次if语句。我们假设if语句的执行次数为T(n, m, o),那么我们可以进一步得到:T(n, m, o) = T(n-1, m+1, o) + T(n-1, m, o+1)(当n > 0时)。我们可以看到base case与参数m, o无关,因此我们可以把以上表达式进一步简化为T(n) = 2T(n-1),由此我们可得T(n) = 2T(n-1) = (2^2) * T(n-2)......所以我们可以得到以上算法的时间复杂度为O(2^n)

3.

【京东】如下程序的时间复杂度为____(其中m > 1e > 0

x = m;

y = 1;

while (x - y > e) {

    x = (x + y) / 2;

    y = m / x;

}

print(x);

    以上算法的关键操作即while语句中的两条赋值语句,我们只需要计算这两条语句的执行次数即可。我们可以看到,当x - y > e时,while语句体内的语句就会执行,x = (x + y) / 2使得x不断变小(当y<<x时,执行一次这个语句会使x变为约原来的一半),假定y的值固定在1,那么循环体的执行次数即为~logm,而实际情况是y在每次循环体最后都会被赋值为m / x,这个值总是比y在上一轮循环中的值大,这样一来x-y的值就会更小,所以以上算法的时间复杂度为O(logm)

4.

【搜狗】假设某算法的计算时间可用递推关系式T(n) = 2T(n/2) + nT(1) = 1表示,则该算法的时间复杂度为____

    根据题目给的递推关系式,我们可以进一步得到:T(n) = 2(2T(n/4) + n/2) + n = ...将递推式进一步展开,我们可以得到该算法的时间复杂度为O(nlogn)

 

1 0