【算法分析与设计】算法分析示例

算法分析示例

以下算法都是基于Python 3

算法分析就是通过优化时间复杂度和空间复杂度,让算法变得更…快

前缀平均值:

前缀平均值就是求这个数之前列表中的所有数的平均值,把这些平均值放在一个新的列表中.

二次 - 时间算法:

def prefix_average1(S):
    n = len(S)
    A = [0] * n
    for j in range(n):
        total = 0
        for i in range(j+1):
            total += S[i]
        A[j] = total/(j+1)
    return A

分析:

1.算法开始时,n = len(S) ,且时间固定
2.第二行 A = [0]*n ,用于创建和初始化python列表,列表长度为n,每个元素的值为0,所以每个元素都执行相同的时间,运行	   时间为O(n).
3.for 循环有两层嵌套,分别有计数器j和i独立约束,外层循环执行n次因此total = 0和 A[j] = total/(j+1) 语句都会执   行n次运行时间为O(n).
4.内层循环被计数器i约束,执行j+1,语句total += s[i]共执行  1+2+3+4+.....+n次 ,也就是 n*(n+1)/2,所以时间复杂度为O(n2)

>>>所以上面算法的时间复杂都为O(n2)

可以得到上面算法在求前缀平均值时时间复杂度高.所以进行优化

def prefix_average2(S):
    n = len(S)
    A = [0] * n
    for j in range(n):
    	A[j] = 	sum(S[0:j+1]/(j+1))
    return A

优化: for 循环有只有一层嵌套了,但是sum函数在进行计算时,sum(S[0:j+1]/(j+1))函数也是一个内部方法,在规模上这个算法已经没有可以优化的地方了,但是在时间上却没有减少,sum()函数按比例运行时间为1+2+3+4+....+n所以整个算法还是一个二次时间算法

线性时间算法

为了优化时间复杂度,所以对代码进行了重写

def prefix_average3(S):
    n = len(S)
    A = [0] * n
    total = 0
    for j in range(n):
    	total += S[i]
         A[j] = total/(j+1)
    return A

优化:保留了一层 for循环
     并且在上面两个算法中,每次循环都会对前面的n象的和进行相加,提高了时间复杂度,所以我们定义total让他累加,并在循环中只对他除(j+1),时间复杂度大大降低

>>>时间复杂度 O(n)

三集不相交

算法1

def disjoint1(A,B,C):
    for a in A:
        for b in B:
            for c in C :
                if a==b==c:
                    return False
    return True

对于上述算法,只是简单的遍历了一遍三个序列任何以组可能的值,并确定是否相等,在最坏的情况下,算法时间复杂度为O(n3)
>>>时间复杂度O(n3)

算法2

​ 可以使用一个简单的观测来提高渐进性, 比如,当在b中找到了和a相同的元素时,不必再去c中寻找,而是直接开始另一轮循环,来解决上面的问题

def disjoint2(A,B,C):
    for a in A:
        for b in B:
            if a == b:
                for c in C :
                    if a==c:
                        return False
    return True

虽然还是三层循环,但是当代码执行到第三层循环时,剩下的时间取决于找到多少对匹配了的a和b,所以 for循环在c上的时间复杂度只有O(n2)
>>>时间复杂度O(n2)

元素唯一性

给定一个有n个元素的序列S,求该集合内的所有元素都彼此不同

算法1

def unique1(S):
    for j in range(len(S)):
        for k in range(j+1,len(S)):
            if S[j] == S[k]:
                return False
    return True

通过简单的迭代来判断两个元素,所以最坏的情况下,算法比例增长倒 (n-1)+(n-2)+.....+2+1
>>>时间复杂度 O(n2)

算法2

通过分析,如果能减少比较次数的话,那么时间复杂度会大大降低,

所以引入了排序算法sorted(),在排序算法中,只用比较相邻的两个数,如果相等就可以得出元素不唯一

def unique1(S):
    temp = sorted(S)
    for i in range(1,len(temp)):
        if temp[i-1] == temp[i]:
            return False
    return True

排序后,下面的比较就变成了O(n),sorted()排序算法本身在最坏的情况下,经历O(n log n)可以算出来
>>>时间复杂度 O(n log n)
            参考资料 :机械工业出版社:数据结构与算法 .迈克尔.T.古德里奇
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值