1. 程式人生 > >常見的python演算法題

常見的python演算法題

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()