一、时间复杂度
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(b−1)
= 3 + ( 3 + t ( b − 2 ) ) = 3 + (3 + t(b-2)) =3+(3+t(b−2))
. . . ... ...
= 3 k + t ( b − k ) = 3k + t(b - k) =3k+t(b−k)
# b - k = 1 停止
= 3 ( b − 1 ) + t ( 1 ) = 3(b - 1) + t(1) =3(b−1)+t(1)
= 3 b − 3 + 2 = 3b - 3 + 2 =3b−3+2
= 3 b − 1 = 3b - 1 =3b−1
复杂度表达式:
-
O(n) # linear
2、对数(Log)
平方问题优化
可以减半规模 b even (偶数)
a b = ( a ∗ a ) ( b / 2 ) a^b = (a * a) ^{ (b / 2)} ab=(a∗a)(b/2)
可以减半规模 b odd(奇数)
a b = a ∗ ( a ( b − 1 ) ) a^b = a * ( a ^ {(b - 1)} ) ab=a∗(a(b−1))
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(b−1))=12+t(2(b−1)) - 奇数时(b odd)
t ( b ) = 6 + t ( b − 1 ) t(b) = 6 + t(b-1) t(b)=6+t(b−1)
= 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(b−1)))=12+t(2(b−1))
问题简单化:假定
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(n−1)
=
1
+
(
t
(
1
)
+
2
∗
t
(
n
−
1
)
)
= 1 + (t(1) + 2*t(n-1))
=1+(t(1)+2∗t(n−1))
=
3
+
2
∗
t
(
n
−
1
)
= 3 + 2 * t(n-1)
=3+2∗t(n−1)
所以:
t
(
n
)
=
3
+
2
(
3
+
2
∗
t
(
n
−
2
)
)
t(n) = 3 + 2(3 + 2 * t(n-2))
t(n)=3+2(3+2∗t(n−2))
=
3
+
2
∗
3
+
2
∗
2
∗
t
(
n
−
2
)
= 3 + 2*3 + 2*2*t(n-2)
=3+2∗3+2∗2∗t(n−2)
=
3
+
2
∗
3
+
2
∗
2
∗
(
3
+
2
∗
t
(
n
−
3
)
)
= 3 + 2*3 + 2*2*(3 + 2 * t(n-3))
=3+2∗3+2∗2∗(3+2∗t(n−3))
=
3
+
2
∗
3
+
2
∗
2
∗
3
+
2
3
∗
t
(
n
−
3
)
= 3 + 2*3 + 2*2*3 + 2^3 * t(n-3)
=3+2∗3+2∗2∗3+23∗t(n−3)
.
.
.
...
...
=
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)+2k∗t(n−k)
# 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(n−1))+2(n−1)∗2
=
3
(
2
(
n
−
1
)
−
1
)
+
2
n
= 3(2^{(n-1)} -1 ) + 2^{n}
=3(2(n−1)−1)+2n
=
3
∗
2
n
/
2
+
2
n
−
3
= 3 * 2^{n} / 2 + 2^{n} -3
=3∗2n/2+2n−3
=
5
2
∗
2
n
/
2
−
3
= \frac{5}{2} * 2^{n}/2 - 3
=25∗2n/2−3
-
复杂度表达式:
-
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)