常見的python演算法題
阿新 • • 發佈:2019-01-06
1.二分法
二分查詢,給出一個已經排好序的列表,注意是已經排好序的,查詢指定元素在列表中的位置
# -*- coding: utf-8 -*-
def binary_search(list,item):
low = 0
high = len(list)-1
while low<=high:
mid = (low+high)/2
print "中位數%s" %mid
guess = list[mid]
print "中位數的值%s" % guess
print "輸入的值%s" % item
if guess>item:
high = mid-1
print "5>3"
elif guess<item:
low = mid+1
print "5<3"
else:
print high
print low
return mid
return None
mylist = [1,3,5,7,9]
print binary_search(mylist,3)
def binarysearch(target,sortedlist):
left = 0
right = len(sortedlist)-1
while left < right:
midpoint = (left+right) // 2
if target == sortedlist[midpoint]:
return midpoint
elif target > sortedlist[midpoint]:
left = midpoint+1
else:
right = midpoint-1
return "not found"
alist = [1,3,5,8,0]
target = 8
print(binarysearch(target, alist))
輸出:
3
2.選擇排序
# -*- coding: utf-8 -*-
#選擇排序
#選擇排序,主要思想,找到陣列中最小的元素,然後往新數組裡追加,時間複雜度O(n^2)
def FindSmallest(arr):
print "array now is %s" %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
print FindSmallest([1,3,5,2])
def selectionSore(arr):
newarr = []
for i in range(len(arr)):
#關鍵點:arr重建,刪掉上次得出的,在執行下次取新的arr裡面最小的
newarr.append(arr.pop(FindSmallest(arr)))
print newarr
selectionSore([1,3,5,2,4])
另一種選擇排序的寫法
def swap(lyst,i,j):
temp = lyst[i]
lyst[i]=lyst[j]
lyst[j]=temp
def selectsort(lyst):
i=0
while i<len(lyst)-1:
minindex = i
j = i+1
while j<len(lyst):
if lyst[j]<lyst[minindex]:
minindex = j
j+=1
if minindex != i:
swap(lyst,i,minindex)
i+=1
2.5.氣泡排序
def bubbleSort(lyst):
n = len(lyst)
while n>1:
i = 1
while i<n:
if lyst[i] < lyst[i-1]:
swap(lyst,i,i-1)
i +=1
n -= 1
3.快速排序
#快速排序,遞迴演算法 O(nlogn)
# -*- coding: utf-8 -*-
#遞迴快速排序
def quicksort(list):
if len(list)<2:
return list #基線條件,為空或者只包含一個元素的陣列是有序的
midpivot = list[0]#遞迴條件
lessbeforemidpivot = [i for i in list[1:] if i<=midpivot]#小於基準值的元素組成的子陣列
biggeraftermidpivot = [i for i in list[1:] if i > midpivot]#大於基準值的元素組成的子陣列
finallylist = quicksort(lessbeforemidpivot)+[midpivot]+quicksort(biggeraftermidpivot)
return finallylist
print quicksort([2,4,6,7,1,2,5])
4.廣度優先搜尋
# -*- coding: utf-8 -*-
#廣度優先搜尋
from collections import deque
graph = {}
graph["you"] = ["alice",'bob',"calm"]
graph["alice"] = ["peggym"]
graph["bob"] = ["anuj","peggym"]
graph["peggym"] = ["anuj"]
graph["anuj"] = ["peggym"]
# print type(graph)
def person_is_seller(persion):
if "m" in persion:
return True
def search(name):
search_queue = deque()
# print type(search_queue)
search_queue += graph[name]
# print type(search_queue)
# print (search_queue)
searched = []
while search_queue:
person = search_queue.popleft()
if person not in searched:
if person_is_seller(person):
print person+" is a mango seller!"
searched.append(person)
else:
search_queue += graph[person]
searched.append(person)
# print (search_queue)
return False
search("you")
4.狄克斯特拉演算法
# -*- coding: utf-8 -*-
#狄克斯特拉演算法
# 同時儲存鄰居和前往鄰居的開銷
graph = {}
graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2
graph["a"] = {}
graph["a"]["fin"] = 1
graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5
graph["fin"] = {}
# 從開始處到每個節點的開銷散列表
infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity #終點視為無窮大
#儲存父節點的散列表
parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None
# 記錄處理過的節點的陣列
processed = []
# 找出開銷最低的節點
def find_lowest_cost_node(costs):
lowest_cost = float("inf")
lowest_cost_node = None
for node in costs:#遍歷所有節點
cost = costs[node]#獲取節點消費
if cost<lowest_cost and node not in processed: #如果當前節點的開銷更低而且沒被處理過
lowest_cost = cost #就將其視為最低的節點
lowest_cost_node = node
return lowest_cost_node
node = find_lowest_cost_node(costs)#在沒處理的節點裡面找到開銷最小的節點
while node is not None: #節點都處理完之後結束迴圈
cost = costs[node] #b的開銷2
neighbors = graph[node] #b節點接下來能走到a和fin節點
for n in neighbors.keys():#枚舉出b節點接下來能走到的a和fin節點
new_cost = cost+neighbors[n] #新節點的開銷等於b節點的開銷加上b分別加上後面的a和fin的開銷
if costs[n] > new_cost: #如果單獨到達a和fin的開銷大於從b走的開銷
costs[n] = new_cost #就更新到達這一點的開銷的為更小的從b走的記錄代替直接走到a的原來的記錄
parents[n] = node #將a的父節點設為b節點
processed.append(node)
node = find_lowest_cost_node(costs)
5.貪婪演算法
貪心法,又稱貪心演演算法、貪婪演演算法、或稱貪婪法,是一種在每一步選擇中都採取在當前狀態下最好或最優(即最有利)的選擇,從而希望導致結果是最好或最優的演算法
# -*- coding: utf-8 -*-
#貪婪演算法
# 包含需要覆蓋的州的列表,用集合表示,不包含重複元素
states_needed = set(["mt","wa","or","id","nv","ut","ca","az"])
#可供選擇的廣播臺清單,用散列表表示
stations = {}
stations["kone"] = set(["id","nv","ut"])
stations["ktwo"] = set(["wa","id","mt"])
stations["kthree"] = set(["or","nv","ca"])
stations["kfour"] = set(["nv","ut"])
stations["kfive"] = set(["ca","az"])
print stations
# 使用一個集合來儲存最終的廣播臺
final_stations = set()
while states_needed:
best_station = None
states_covered = set()#被選中的廣播臺覆蓋的州,遍歷完一遍,沒有清空states_needed的話就會重走一遍,重置states_covered
# 遍歷出每個臺覆蓋的州
for station, states in stations.items():
print "遍歷到的臺%s" %station
covered = states_needed & states #看這個臺覆蓋的州和需要覆蓋的州里面重合的
print "這個臺覆蓋的州和需要覆蓋的州里面重合的%s" %covered
if len(covered)>len(states_covered):
print "重合的比上一個包含的states_covered多的時候"
best_station = station
print "上次states_covered為%s" % states_covered
states_covered = covered
print "更新states_covered為%s" %states_covered
states_needed -= states_covered
print "還沒覆蓋的州%s"%states_needed
final_stations.add(best_station)
print "已經選出的臺%s" % best_station
print final_stations
6. O(1)時間複雜度實現入棧出棧獲得棧中最小元素最大元素
#定義棧結構,根據棧的後進先出特性,增加輔助棧,來儲存當前狀態下資料棧中的最小、最大元素。
class Stack(object):
def __init__(self):
self.data = []
self.minValue = []
self.maxValue = []
def push(self,data):
self.data.append(data)
if len(self.minValue)==0:
self.minValue.append(data)
else:
if data <= self.minValue[-1]:
self.minValue.append(data)
if len(self.maxValue)==0:
self.maxValue.append(data)
else:
if data>=self.maxValue[-1]:
self.maxValue.append(data)
def pop(self):
if len(self.data)==0:
return None
else:
temp = self.data.pop()
if temp == self.minValue[-1]:
self.minValue.pop()
if temp == self.maxValue[-1]:
self.maxValue.pop()
return temp
def min(self):
if len(self.data)==0:
return None
else:
return self.minValue[-1]
def max(self):
if len(self.data)==0:
return None
else:
return self.maxValue[-1]
def show(self):
print("stack data")
for data in self.data:
print(data)
print("min",self.min())
print("max",self.max())
if __name__ == "__main__":
s = Stack()
s.push(2)
s.push(1)
s.show()
s.push(4)
s.push(3)
s.push(2)
s.show()
s.pop()
s.show()
s.pop()
s.show()