文章目錄
1、框架思維
所謂框架,就是說不管具體問題是什麼,這些代碼都是永遠無法脫離的結構,你可以把這個結構作爲大綱,根據具體問題在框架上添加代碼就行了。
萬變不離其宗
- 我們分析問題,一定要有遞歸的思想,自頂向下,從抽象到具體
- 散列表、棧、隊列、堆、樹、圖都屬於「上層建築」,而數組和鏈表纔是「結構基礎」
- 最高層的抽象,數據結構只有兩種:數組和鏈表
- 隊列、棧這兩種數據結構既可以使用鏈表也可以使用數組實現
- 「圖」的兩種表示方法,鄰接表就是鏈表,鄰接矩陣就是二維數組
- 「散列表」就是通過散列函數把鍵映射到一個大數組裏
- 「樹」,用數組實現就是「堆」,因爲「堆」是一個完全二叉樹,用數組存儲不需要節點指針,操作也比較簡單;用鏈表實現就是很常見的那種「樹」,因爲不一定是完全二叉樹,所以不適合用數組存儲。在這種鏈表「樹」結構之上,又衍生出各種巧妙的設計,比如二叉搜索樹、AVL 樹、紅黑樹、區間樹、B 樹
操作,無非遍歷 + 訪問==增刪查改
- 兩種形式,線性的和非線性的,線性就是 for/while 爲代表,非線性就是遞歸爲代表
// 數組遍歷框架,典型的線性遍歷結構:
func traverse(arr []int) {
for (i := 0; i < len(arr); i++) {
// 訪問 arr[i]
}
}
// 二叉樹遍歷框架,典型的非線性遞歸遍歷結構:
func traverse(root TreeNode) {
traverse(root.left)
traverse(root.right)
}
// 鏈表遍歷框架,兼具線性和非線性遍歷結構:
func traverse(head ListNode){
for p := head; p!= nil; p=p.Next{
// 訪問p.Val
}
}
func traverse(head ListNode){
// 訪問p.Val
traverse(head.Next)
}
// 二叉樹框架又可以具體擴展爲 N 叉樹的遍歷框架:
func traverse(root TreeNode) {
for child := range root.children{
traverse(child)
}
}
// N 叉樹的遍歷又可以擴展爲圖的遍歷,圖就是好幾 N 叉棵樹的結合體
算法框架小結
- 對於一個初學算法的人來說,一定要學會從框架上看問題,而不要糾結於細節問題,當然,如果細節出錯,你得不到正確的答案,但是只要有框架在,你再錯也錯不到哪去,因爲你的方向是對的
- 啥叫從框架上看問題?比如說前文 動態規劃 中湊零錢的問題,如果你看了一眼代碼就自動排除細節問題,直接提取出 N 叉樹遍歷框架,那麼你的框架思維就到位了
2、可視化
數據結構在線模擬器
-
在線網址:https://iacj.github.io/react-datastructer/#/ | https://github.com/IACJ/react-datastructer
-
VisuAlgo: https://visualgo.net/zh | https://visualgo.net/en
-
Data Structure Visualizations : https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
-
Algorithm Visualizer: https://algorithm-visualizer.org/
-
LeetCodeAnimation:https://github.com/MisterBooo/LeetCodeAnimation
算法複雜度速查表
四個基礎數據結構:
(數組、鏈表、棧、隊列)、散列表、(二叉樹、堆、跳錶、Trie 樹)、圖
1、數組、鏈表、棧、隊列
2、散列表
3、樹
4、圖
四個基礎算法:
排序、(二分查找、搜索)、(哈希算法、貪心算法、分治算法、回溯算法、動態規劃)、字符串匹配