時間復雜度
- 時間復雜度是用來估計算法運行時間的一個式子(單位)。
- 一般來說,時間復雜度高的算法比復雜度低的算法慢。
- 常見的時間復雜度(按效率排序)
- O(1) < O(log n) < O(n) < O(n log n) < O(n 2) < O(n 2 log n) < O(n 3)
- 不常見的時間復雜度(看看就好)
- n O(n!) O(2 n) O(n n) …
- 如何一眼判斷時間復雜度?
- 循環減半的過程 -->O(logn)
- 幾次循環就是n的幾次方的復雜度
空間復雜度
- 空間復雜度:用來評估算法內存占用大小的一個式子
- “空間換時間”
漢諾塔問題
-
大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞着64片黃金圓盤。
大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。
在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。
64根柱子移動完畢之日,就是世界毀滅之時。
def hanoi(n, A, B, C):
if n > 0:
hanoi(n-1, A, C, B)
print('%s->%s' % (A, C))
hanoi(n-1, B, A, C)
hanoi(5, 'A', 'B', 'C')
#h(n) = 2h(n-1)+1
#h(1)=1
遞歸面試題 斐波那契
- 一段有n個台階組成的樓梯,小明從樓梯的最底層向最高處前進,它可以選擇一次邁一級台階或者一次邁兩級台階。問:他有多少種不同的走法?
# 斐波那契 數列
f(n) = f(n-1) + f(n-2)
from sys import setrecursionlimit
from cal_time import cal_time
setrecursionlimit(1000)
# O(2^n)
# f(n) = f(n-1) + f(n-2)
# 一個問題的解決可以依賴於其子問題的解決的時候
def fib(n):
if n == 0 or n == 1:
return 1
else:
return fib(n-1) + fib(n-2)
# O(n)
def fib2(n):
li = [1,1]
for i in range(2, n+1):
li.append(li[-1]+li[-2])
return li[-1]
def fib3(n):
li = [-1 for i in range(n+1)]
def fib(n):
if n == 0 or n == 1:
return 1
elif li[n] >= 0:
return li[n]
else:
v = fib(n-1) + fib(n-2)
li[n] = v
return li[n]
return fib(n)
# 1 2
# O(n)
def fib4(n):
a = 1
b = 1
c = 1
for i in range(2, n+1):
c = a + b
a = b
b = c
return c
@cal_time
def fibnacci(n):
return fib4(n)
print(fibnacci(400))
列表查找
-
列表查找:從列表中查找指定元素
輸入:列表、待查找元素
輸出:元素下標或未查找到元素
-
順序查找 on
從列表第一個元素開始,順序進行搜索,直到找到為止。
-
二分查找 logn
從有序列表的候選區data[0:n]開始,通過對待查找的值與候選區中間值的比較,可以使候選區減少一半。
二分查找
from cal_time import cal_time
# 時間復雜度 : log n
def binary_search(li, val):
low = 0
high = len(li)-1
while low <= high: # 只要候選區有值
mid = (low + high) // 2
if val == li[mid]:
return mid
elif val < li[mid]:
high = mid - 1
else: # val > li[mid]
low = mid + 1
return -1
# 遞歸與迭代
# 一般遞歸會慢
# 尾遞歸 : 編譯器會優化成迭代 但是Python沒有針對尾遞歸進行優化
def bin_search_rec(data_set, value, low, high):
if low <= high:
mid = (low + high) // 2
if data_set[mid] == value:
return mid
elif data_set[mid] > value:
return bin_search_rec(data_set, value, low, mid - 1)
else:
return bin_search_rec(data_set, value, mid + 1, high)
else:
return