文章目录
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、图
四个基础算法:
排序、(二分查找、搜索)、(哈希算法、贪心算法、分治算法、回溯算法、动态规划)、字符串匹配