前置知识:
(1)并查集:
Note:
1.find 目的找到元素的老大 (链表遍历逐层向上找)
2.merge 合并集合(实质改变集合老大,链表性质)
树:
最小生成树:
求最小路径和(Kruskal算法):
(1)再畅通工程(最小生成树)-CSDN博客(空白图)
Note: 先排序结点距离,从小到大利用并查集找结点老大,取较小序号结点作为两结点老大
function KruskalMST(Graph):
# 初始化化并查集(老大设为自己)
# 边按权重从小到大排序
从小到大利用并查集找结点老大,取较小序号结点作为两结点老大
for each edge in Graph.edges:
如果属于同一个集合,跳过这条边(添加这条边会形成环)。
if ds.find_set(edge.node1) != ds.find_set(edge.node2):
MST.append(edge)
ds.union(edge.node1, edge.node2)
如果最小生成树中的边数等于节点数减一,则停止添加边。
if length(MST) == length(Graph.nodes) - 1:
break
return MST
(2)继续畅通工程(最小生成树+并查集)-CSDN博客(有部分边存在)
Note: 一旦路径已建好,将其长度值赋值为0,然后所有路径一致看待
function KruskalMST(Graph):
# 初始化化并查集(老大设为自己)
# 输出结点距离,判断是否存在,若存在,距离赋值为0
# 边按权重从小到大排序
从小到大利用并查集找结点老大,取较小序号结点作为两结点老大
for each edge in Graph.edges:
如果属于同一个集合,跳过这条边(添加这条边会形成环)。
if ds.find_set(edge.node1) != ds.find_set(edge.node2):
MST.append(edge)
ds.union(edge.node1, edge.node2)
如果最小生成树中的边数等于节点数减一,则停止添加边。
if length(MST) == length(Graph.nodes) - 1:
break
return MST
(3)问题 Q: 小希的迷宫(并查集+最小生成树)-CSDN博客(知所有边,判断是否成环,同老大)
Note: 给出相应图路径,
function init(n):
for i = 1 to n:
parent[i] = i # 每个节点的父节点初始化为自己
# 判断是否同集合的数据再次出现,否则dec=0输出No
rootX = find(x),rootY = find(y)
if rootX != rootY:
if rank[rootX] > rank[rootY]:
parent[rootY] = rootX
elif rank[rootX] < rank[rootY]:
parent[rootX] = rootY
else:
dec=0
# 判断所有结点老大是否相同,否则输出No
for i = 1 to n:
if dec1 ==1:
if find(i) != i
unique_leader=find(i)
dec1=0;
else:
if find(i) != unique_leader:
dec=0
二叉树:
特殊类型:
对称二叉树:
思路:需要额外构建check对比递归函数,对称性传入参数
二叉树属性
二叉树直径:
思路:遍历时更新最大距离(左右子树最大深度之和)
遍历:
层序遍历:
思路:深搜,以不同layer区分元素属于列表,添加对应列表的元素
图:
最短路径(dijkstra):
(1)最短路径—Dijkstra算法及 变式题(一个人的旅行)-CSDN博客
Note: 不断运行广度优先算法找可见点,计算并更新可见点到源点的最短距离长度
function dijkstra(Graph, source):
dist[] = ∞ for all vertices
prev[] = undefined for all vertices
dist[source] = 0
priority_queue = new MinHeap()
priority_queue.insert(source, 0)
while not priority_queue.isEmpty():
u = priority_queue.extractMin()
for each neighbor v of u:
alt = dist[u] + weight(u, v)
if alt < dist[v]:
dist[v] = alt
prev[v] = u
priority_queue.decreaseKey(v, alt)
return dist, prev
链表:
相交链表:
返回相交起点
思路: 遍历结束,更新为对方头节点(刚结束两次后,PA,PB同时指向起始点)
代码:
ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) {
ListNode* PA = headA;
ListNode* PB = headB;
while (PA != PB) {
PA = PA ? PA->next : headB;
PB = PB ? PB->next : headA;
}
return PA;
}
回文链表:
思路:原链表前半部分比较反转后半部分的链表
环形链表:
141. 环形链表(快慢指针 + Floyd 判圈算法)-CSDN博客
思路:无环,快慢不相遇;有环,快慢必相遇
栈
栈操作 + 匹配表(函数 or 哈希表)
Note: 遍历字符串中的字符,左括号入栈,右括号 映射元素 栈顶元素匹配。