算法性能分析

算法性能分析

时间复杂度分析

递归算法的时间复杂度

例题一: 求x的n次方

用一道题目,同样使用递归算法, 有的写出了O(n)的代码,有的写出了O(longn)的代码

时间复杂度为:O(n)

最直观的写法, 一个for循环求出结果,代码如下:

def sample_1(x, n):
    result = 1
    for i in range(n):
        result = result * x

    return result

思考: 有没有效率更好的算法?
有的人一看到递归,就想到了O(logn), 其实并不是这样, 递归算法的时间复杂度本质上是要看-递归的次数 * 每次递归中的操作数
代码如下:

def sample_1_2(x, n):
    if n == 0:
        return 1

    return sample_1_2(x, n)

使用迭代更改之后,时间复杂度为O(n), 每次n-1,递归了n次时间复杂度为O(n), 每次进去了一个乘法的操作,复杂度为O(1),总的时间复杂度为O(n * 1)

再次改进尝试:

def sample_1_3(x n):
    if n == 0:
        return 1
    if n % 2 == 1:
        return sample_1_3(x, n//2) * sample_1_3(x, n//2) * x

    return sample_1_3(x, n//2) * sample_1_3(x, n//2)

上述代码时间复杂度,如何计算?

首先查看递归了多少次?可以将递归抽象成一颗满二叉树来表示,每个节点代表着一次递归并进行了一次乘法的操作,则递归的次数为节点的个数,所有节点的个数为一个公比为2等比数列的求和使用sum = 2^(m + 1) -1表示,x的n次方,需要递归的次数为sum,则递归
次数,将m使用n表示,忽略常数项-1,则m=logn -1, 得到sum = n -1,所以时间复杂度仍然为O(n)。

查看上述代码,去除冗余的部分,我们可以得到下面的代码:

def sample_1_4(x, n):
    if n == 0:
        return 1
    t = sample_1_4(x, n//2)
    if n % 2 == 1:
        return t * t * x
    
    return t * t

可以看到这里仅仅有一个递归调用,且每次都是n/2, 所以这里是log以2为底的对数次。 每次递归都是做了一次乘法操作, 时间复杂度为O(logn).

空间复杂度分析

概念: 是对一个算法在运行过程中占用内存空间大小的量度,记做S(n)=O(f(n)

空间复杂度(Space Complexity)记作S(n) 依然使用大O来表示。利用程序的空间复杂度,可以对程序运行中需要多少内存有个预先估计

常见问题

  1. 口那个键复杂度是否是可执行文件大小?
    空间复杂度是考虑程序运行时占用内存的大小,而不是可执行文件的大小
  2. 空间复杂度是准确算出程序运行时所占内存?
    空间复杂度是预先大体评估程序内存使用的大小。
    空间复杂度是logn的情况确实有些特殊,其实是在递归的时候,会出现空间复杂度为logn的情况。
posted @ 2022-08-16 11:43  酷酷的排球  阅读(89)  评论(0编辑  收藏  举报