MIT_计算机科学与程序:算法复杂度笔记

一、时间复杂度

1、线性(Linear)

def exp2(a, b):
    if b == 1# 1 times
        return a # 1 times
    else: 
        return a * exp2(a, b-1) # 2 times

exp2(2, 4)
总共操作次数如下
t ( b ) = 3 + t ( b − 1 ) t(b) = 3 + t(b-1) t(b)=3+t(b1)
         = 3 + ( 3 + t ( b − 2 ) ) = 3 + (3 + t(b-2)) =3+(3+t(b2))
         . . . ... ...
         = 3 k + t ( b − k ) = 3k + t(b - k) =3k+t(bk)
         # b - k = 1 停止
         = 3 ( b − 1 ) + t ( 1 ) = 3(b - 1) + t(1) =3(b1)+t(1)
         = 3 b − 3 + 2 = 3b - 3 + 2 =3b3+2
         = 3 b − 1 = 3b - 1 =3b1
复杂度表达式
O(n) # linear

2、对数(Log)

平方问题优化
可以减半规模 b even (偶数)
a b = ( a ∗ a ) ( b / 2 ) a^b = (a * a) ^{ (b / 2)} ab=(aa)(b/2)
可以减半规模 b odd(奇数)
a b = a ∗ ( a ( b − 1 ) ) a^b = a * ( a ^ {(b - 1)} ) ab=a(a(b1))

def exp3(a, b):
    if b == 1# 1 times
        return a   # 1 times
    if ( b % 2) * 2 == b: #  3 times
        return exp3(a * a, b / 2)  # 2 times
    else: return a * exp3(a, b-1) # 2 times
问题简化
  • 偶数时(b even)
    t ( b ) = 6 + t ( b 2 ) t(b) = 6 + t(\frac{b}{2}) t(b)=6+t(2b)
             = 6 + ( 6 + t ( b − 1 ) ) = 12 + t ( ( b − 1 ) 2 ) = 6 + (6 + t(b-1)) = 12 + t(\frac{(b-1)}{2}) =6+(6+t(b1))=12+t(2(b1))
  • 奇数时(b odd)
    t ( b ) = 6 + t ( b − 1 ) t(b) = 6 + t(b-1) t(b)=6+t(b1)
             = 6 + ( 6 + t ( ( b − 1 ) 2 ) ) = 12 + t ( ( b − 1 ) 2 ) = 6 + (6 + t(\frac{(b-1)}{2})) = 12 + t(\frac{(b-1)}{2}) =6+(6+t(2(b1)))=12+t(2(b1))

问题简单化:假定
t ( b ) = 12 + t ( b 2 ) t(b) = 12 + t(\frac{b}{2}) t(b)=12+t(2b)
         = 12 + ( 12 + t ( b 4 ) ) = 12 + (12 + t(\frac{b}{4})) =12+(12+t(4b))
         . . . ... ...
         = 12 k + t ( b 2 k ) = 12k + t(\frac{b}{2^k}) =12k+t(2kb)

b/(2**k) = 1 停止
k = log2b

         = 12 l o g 2 b + t ( 1 ) = 12log_2b + t(1) =12log2b+t(1)
         = 12 l o g 2 b + 2 = 12log_2b + 2 =12log2b+2

复杂度表达式
O(logb) # log

3、平方(Square)

def g(n , m):
    x = 0  # 1 times
    for i in range(n):   
        for j in range(m):  
            x += 1 # n * m times
    return  x # 1 times

g(100, 100)
复杂度表达式
O(n * m)O(n ** 2)

3、指数(Exp)

def Tower(size, fromStack, toStack, spareStack):
    if size == 1: # 1 times 
        print('Move disk from {} to {}'.format(fromStack, toStack)) # 1 times 
    else:
        Tower(size - 1, fromStack,  spareStack , toStack)
        Tower(1, fromStack,  toStack , spareStack)
        Tower(size - 1, spareStack,  toStack , fromStack)


Tower(2, 'f', 's', 't')
"""
Move disk from f to t
Move disk from f to s
Move disk from t to s
"""
Tower(5, 'f', 's', 't')

函数操作的通式:
t ( n ) = 1 + t ( n − 1 ) t(n) = 1 + t(n - 1) t(n)=1+t(n1)
         = 1 + ( t ( 1 ) + 2 ∗ t ( n − 1 ) ) = 1 + (t(1) + 2*t(n-1)) =1+(t(1)+2t(n1))
         = 3 + 2 ∗ t ( n − 1 ) = 3 + 2 * t(n-1) =3+2t(n1)
所以:
t ( n ) = 3 + 2 ( 3 + 2 ∗ t ( n − 2 ) ) t(n) = 3 + 2(3 + 2 * t(n-2)) t(n)=3+2(3+2t(n2))
         = 3 + 2 ∗ 3 + 2 ∗ 2 ∗ t ( n − 2 ) = 3 + 2*3 + 2*2*t(n-2) =3+23+22t(n2)
         = 3 + 2 ∗ 3 + 2 ∗ 2 ∗ ( 3 + 2 ∗ t ( n − 3 ) ) = 3 + 2*3 + 2*2*(3 + 2 * t(n-3)) =3+23+22(3+2t(n3))
         = 3 + 2 ∗ 3 + 2 ∗ 2 ∗ 3 + 2 3 ∗ t ( n − 3 ) = 3 + 2*3 + 2*2*3 + 2^3 * t(n-3) =3+23+223+23t(n3)
         . . . ... ...
         = 3 ( 1 + 2 + 4 + 6 + . . . + 2 k ) + 2 k ∗ t ( n − k ) = 3( 1 + 2 + 4 + 6 +...+ 2^k) + 2^k * t(n-k) =3(1+2+4+6+...+2k)+2kt(nk)
         # n-k = 1 时结束 k = n-1
         = 3 ( 1 + 2 + 4 + 6 + . . . + 2 ( n − 1 ) ) + 2 ( n − 1 ) ∗ 2 = 3( 1 + 2 + 4 + 6 +...+ 2^{(n-1)}) + 2^{(n-1)} * 2 =3(1+2+4+6+...+2(n1))+2(n1)2
         = 3 ( 2 ( n − 1 ) − 1 ) + 2 n = 3(2^{(n-1)} -1 ) + 2^{n} =3(2(n1)1)+2n
         = 3 ∗ 2 n / 2 + 2 n − 3 = 3 * 2^{n} / 2 + 2^{n} -3 =32n/2+2n3
         = 5 2 ∗ 2 n / 2 − 3 = \frac{5}{2} * 2^{n}/2 - 3 =252n/23

复杂度表达式
O(2**n)

一、有顺序数组,不同时间复杂度函数比较

def search(s, e):
    """
    在有序list s里查找 e 
    Linear复杂度 O(n)
    """
    ans = None 
    i = 0
    num_comp = 0 
    while i < len(s) and ans == None :
        num_comp += 1
        if e == s[i] :
            ans = True 
        elif e < s[i]:
            ans = False 
        i += 1 
    print(ans, num_comp)


def bsearch(s, e, first, last):
	"""
	二分法
	Log复杂度 O(Logn)
	"""
    print(first, last)
    if (last - first) < 2 : 
        return s[first] == e or s[last] == e 
    mid = first + (last - first) // 2
    if s[mid] == e: return True 
    if s[mid] > e :
        return bsearch(s, e, first , mid - 1)
    else:
        return bsearch(s, e, mid + 1 , last)

def search1(s, e):
    print(bsearch(s, e, 0, len(s) - 1))
    print("Search completed")

def testsearch():
    s = list(range(1000000))
    print("serch in 1000000")
    print('basic -1')
    search(s, -1)
    print('binary -1')
    search1(s, -1)
    print('basic 100000')
    search(s, 100000)
    print('binary 100000')
    search1(s, 100000)

    print("serch in 1000000 * 100")
    s = list(range(100000000))
    print('basic 100000')
    search(s, 100000)
    print('binary 100000')
    search1(s, 100000)

testsearch()

"""
serch in 1000000
basic -1
False 1

binary -1
0 999999
0 499998
0 249998
0 124998
0 62498
0 31248
0 15623
0 7810
0 3904
0 1951
0 974
0 486
0 242
0 120
0 59
0 28
0 13
0 5
0 1
False
Search completed

basic 100000
True 100001

binary 100000
0 999999
0 499998
0 249998
0 124998
62500 124998
93750 124998
93750 109373
93750 101560
97656 101560
99609 101560
99609 100583
99609 100095
99853 100095
99975 100095
99975 100034
99975 100003
99990 100003
99997 100003
True
Search completed
serch in 1000000 * 100
basic 100000
True 100001

binary 100000
0 99999999
0 49999998
0 24999998
0 12499998
0 6249998
0 3124998
0 1562498
0 781248
0 390623
0 195310
97656 195310
97656 146482
97656 122068
97656 109861
97656 103757
97656 100705
99181 100705
99944 100705
99944 100323
99944 100132
99944 100037
99991 100037
99991 100013
99991 100001
99997 100001
100000 100001
True
Search completed
"""

随着运算空间变大,O(Logn)复杂度 显著 优于 0(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Scc_hy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值