圖基礎:
- 定義:描述事物之間的關係。
- 包括:節點集V={V1,V2......,Vn},邊集合E={e1,e2,......,em},其中ei=(vi,vi‘)
- G=<V,E>
- 包括有向圖和無向圖
- 空間複雜度一般爲:O(n+m)或O(n2)
- 主要應用包括:鄰接矩陣,鄰接表
圖的存儲結構:
1、鄰接矩陣表示法:
如果 第 1個點和第 3個點 相連則 matrix[0][2]=1;如果兩節點之間有一條弧,則鄰接矩陣中對應的元素爲1;否則爲0。可以看出,這種表示法非常簡單、直接。但是,在鄰接矩陣的所有n*n 個元素中,只有 m個爲非零元。如果網絡比較稀疏,這種表示法浪費大量的存儲空間,從而增加了在網絡中查找弧的時間。
2、鄰接表表示法:
鄰接表表示法將圖以鄰接表(adjacency lists)的形式存儲在計算機中。所謂圖的鄰接表,也就是圖的所有節點的鄰接表的集合;而對每個節點,它的鄰接表就是它的所有出弧。鄰接表表示法就是對圖的每個節點,用一個單向鏈表列出從該節點出發的所有弧,鏈表中每個單元對應於一條出弧。爲了記錄弧上的權,鏈表中每個單元除列出弧的另一個端點外,還可以包含弧上的權等作爲數據域。圖的整個鄰接表可以用一個指針數組表示。 - 舉例:
拓撲排序基礎:
- 定義:有向無環圖(DAG)
- 場景:任務依賴
- 時間複雜度O(n+m),附加空間複雜度O(n)
- 每次找入度爲0的點(入度就是沒有指向它的箭頭)
- 維護入度
- 過程:
- 應用:假設你有一些任務,以及這些任務之間的任務依賴,每次任務有一個完成時間,假設可以無限並行,最少要多少時間才能完成?
leetcode例題:參考
現在你總共有 n 門課需要選,記爲 0
到 n-1
。
在選修某些課程之前需要一些先修課程。 例如,想要學習課程 0 ,你需要先完成課程 1 ,我們用一個匹配來表示他們: [0,1]
給定課程總量以及它們的先決條件,判斷是否可能完成所有課程的學習?
示例 1:
輸入: 2, [[1,0]]
輸出: true
解釋: 總共有 2 門課程。學習課程 1 之前,你需要完成課程 0。所以這是可能的。
示例 2:
輸入: 2, [[1,0],[0,1]]
輸出: false
解釋: 總共有 2 門課程。學習課程 1 之前,你需要先完成課程 0;並且學習課程 0 之前,你還應先完成課程 1。這是不可能的。
說明:
- 輸入的先決條件是由邊緣列表表示的圖形,而不是鄰接矩陣。詳情請參見圖的表示法。
- 你可以假定輸入的先決條件中沒有重複的邊。
提示:
- 這個問題相當於查找一個循環是否存在於有向圖中。如果存在循環,則不存在拓撲排序,因此不可能選取所有課程進行學習。
- 通過 DFS 進行拓撲排序 - 一個關於Coursera的精彩視頻教程(21分鐘),介紹拓撲排序的基本概念。
-
拓撲排序也可以通過 BFS 完成。
class Solution:
def canFinish(self, numCourses, prerequisites):
"""
:type numCourses: int
:type prerequisites: List[List[int]]
:rtype: bool
"""
graph = collections.defaultdict(list)
indegrees = collections.defaultdict(int)
for u, v in prerequisites:
graph[v].append(u)
indegrees[u] += 1
for i in range(numCourses):
zeroDegree = False
for j in range(numCourses):
if indegrees[j] == 0:
zeroDegree = True
break
if not zeroDegree: return False
indegrees[j] = -1
for node in graph[j]:
indegrees[node] -= 1
return True
最短路基礎:
- 定義:假設E集合(邊集)是有權重的
- 具象:V集合代表城市,E集合代表城市間高速路,權重爲高速路長度,兩點間存在若干條通路,長度最短的通路即最短路
單元最短路(Dijkstra):
- 定義:給定起點s,求到任意點的最短路
- 貪心:每次找最近的點
- 維護s到每個點的距離
- 局部最優等於全局最優
- 時間複雜度O(n2),附加空間複雜度O(n)
- 算法:
- SPFA(Bellman-Ford)算法:參考
單源次短路:
- 給定起點s,求到任意點的次短路(距離大於最短路的最短的路)
- v的次短路:頂點u的最短路再加上u->v的邊,頂點u的次短路再加上u->v的邊
- 在原來的代碼上加入次短路即可
任意兩點最短路(Floyed):
- 求到任兩點間的最短路
- 類似動態規劃:每次加入一個點
- 維護任意兩點間的距離
- 時間複雜度O(n3),附加空間複雜度O(n2)
- 算法:
最小生成樹(Prim):
- 定義:無向圖
- 樹-> 無環(圈)
- 破圈法,避圈法
- 時間複雜度O(n^2)
To be continue......