算法圖解是一本非常簡單入門的算法書,算法基於python語言,簡單易懂,非常好學。不到200頁,學習壓力也不大,入門第一步就是它了。
算法圖解
二分法查找
def binary_search(list,item):
low = 0
high = len(list) - 1
while low <= high:
mid = (low + high )// 2
guess = list[mid]
if guess==item:
return mid
if guess > item:
high = mid - 1
else:
low = mid + 1
return None
my_list = [1,3,5,7,9]
print(binary_search(my_list,3))
print(binary_search(my_list,9))
1.1 128個名字的有序列表二分法需要log128 = 7
1.2 翻倍之後需要8
大O表示法
-
大O表示法指出了最糟情況下的運行時間,算法的快慢指的是並非時間,而是操作數的增加;談論算法的速度時,我們說隨着輸入的增加,其運行時間以什麼樣的速度增加。
-
O(n!)在面對旅行者挑選最優解的時候遇到的算法是非常快的增加,這個我們提出來非常高的難度。
-
大O表示法通常會把常數省略掉
數組和鏈表
O | 數組 | 鏈表 |
---|---|---|
刪除 | O(n) | O(1) |
讀取 | O(1) | O(n) |
插入 | O(n) | O(1) |
鏈表擅長插入和刪除,而數組擅長隨機訪問。
Facebook使用的是一種混合數據結構:鏈表數組
選擇排序
選擇排序的O(n^2)
def findSmallest(arr):
smallest = arr[0]
smallest_index = 0
for i in range(1,len(arr)):
if arr[i]<smallest:
smallest = arr[i]
smallest_index = i
return smallest_index
def selectionSort(arr):
newArr = []
for i in range(len(arr)):
smallest = findSmallest(arr)
newArr.append(arr.pop(smallest))
return newArr
print(selectionSort([5,3,6,2,10]))
遞歸
- 遞歸需要注意:基線條件和遞歸條件;
- 所有的函數調用都進入調用棧,調用棧可能很長,佔用大量的內存空間(注意);
- 使用尾遞歸(高級算法);
- 循環要比遞歸運算更加快速,遞歸更加易懂
>>> def fact(x):
if x == 1:
return x
else:
return x*fact(x-1)
快速排序(review)
設計數組遞歸的時候,通常基線的設置在於[]或者只含有一個元素。
O(nlogn)
def sum(arr):
if len(arr) == 0:
return 0
return arr[0]+sum(arr[1:])
def count(list):
if list == []:
return 0
return 1+count(list[1:])
def quicksort(arr):
if len(arr)<2:
return arr
pivot = arr[0]
less = [i for i in arr[1:] if i <= pivot]
greater = [i for i in arr[1:] if i > pivot]
return quicksort(less) + [pivot] + quicksort(greater)
print(quicksort([10,5,2,3]))
# wow,amazing i love python so much in this way
散列表
哈希表:對於同樣的輸入,散列表必須返回同樣的輸出;
如果存儲在散列表中的同一個位置的時候,就會出現添加一條鏈表;
良好的散列表需要兩個特點:
- 較低的填充因子
- 良好的散列函數