LeetCode | 从树到图:深度剖析数据结构与算法的核心精髓

在 LeetCode 的算法题中,树与图是两类不可或缺的重要数据结构。无论是探索二叉树的深度,还是解决复杂的最短路径问题,树与图的应用无处不在。它们不仅是计算机科学的基石,也是提升算法能力的关键。

1.理论

1.1.树与图的基础概念

1.1.1.树 (Tree)

是一种特殊的图,是无环、连通的图,常见类型有二叉树、二叉搜索树 (BST)、完全二叉树等。

特点:节点之间有父子关系;每个节点最多只有一个父节点,根节点没有父节点;边的数量 = 节点数量 - 1。

1.1.2.图 (Graph)

图是由节点 (Vertices) 和边 (Edges) 组成的结构,可以是有向图或无向图,带权图或无权图。

特点 :可包含环 (Cycle);节点可以没有父子关系;常用的表示方法有邻接矩阵邻接表

1.2.常见问题分类

1.2.1.树的经典问题

二叉树遍历

  • 前序遍历 (Preorder): 根 - 左 - 右
  • 中序遍历 (Inorder): 左 - 根 - 右
  • 后序遍历 (Postorder): 左 - 右 - 根
  • 层序遍历 (Level Order Traversal): 一层一层从上到下遍历。

树的构建

  • 根据前序和中序遍历序列构建二叉树。
  • 根据中序和后序遍历序列构建二叉树。

树的属性

  • 最大深度、最小深度。
  • 是否平衡二叉树。
  • 二叉搜索树的验证。

树的修改与路径

  • 最近公共祖先 (LCA)。
  • 求根到叶子的路径和。
  • 二叉树的直径问题。
1.2.2.图的经典问题

图的遍历:深度优先搜索 (DFS)和广度优先搜索 (BFS)

最短路径问题

  • Dijkstra 算法:单源最短路径,适用于带权图。
  • Bellman-Ford 算法:适用于带权图,允许负权边。
  • Floyd-Warshall 算法:多源最短路径。

连通性问题

  • 判断连通分量的个数。
  • 判断图是否是二分图。

拓扑排序

  • Kahn 算法。
  • 基于 DFS 的拓扑排序。

最小生成树 (MST)

  • Prim 算法:基于贪心。
  • Kruskal 算法:基于边的排序和并查集。

网络流问题:最大流:Edmonds-Karp 算法,Ford-Fulkerson 算法。

1.3.关键算法模板

1.3.1.DFS 模板

python 复制代码
def dfs(node, visited):
    if node in visited:
        return
    visited.add(node)
    for neighbor in graph[node]:
        dfs(neighbor, visited)

1.3.2.BFS 模板

python 复制代码
from collections import deque

def bfs(start):
    queue = deque([start])
    visited = set()
    visited.add(start)

    while queue:
        node = queue.popleft()
        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)

1.3.3.二叉树递归遍历模板

python 复制代码
def inorder_traversal(root):
    if not root:
        return []
    return inorder_traversal(root.left) + [root.val] + inorder_traversal(root.right)

2.真题

2.1.树相关

2.1.1.简单(Easy)

【Leetcode 94】二叉树的中序遍历

给定二叉树的 ,返回其节点值的中序遍历。

如果以空间复杂度优先:Morris 遍历 是最优解,空间复杂度仅为 O(1)

如果以易读性优先:递归解法更清晰简单,适合初学者。

如果需要平衡效率和易读性:迭代解法是最常用的方法。

递归解法

python 复制代码
# 中序遍历的顺序是:左子树 → 根节点 → 右子树。

def inorderTraversal(root):

    def dfs(node):

        if not node:

            return []   #如果当前节点是 None(即递归到达叶子节点的子节点),返回空列表

        return dfs(node.left)+[node.val]+dfs(node.right) #拼接结果

    return dfs(root) 

#时间复杂度:O(n);空间复杂度:O(n)(递归调用栈)

【Leetcode 104】二叉树的最大深度

2.1.2.中等(Medium)

【Leetcode 94】二叉树的中序遍历

2.2.图相关

2.2.2.中等(Medium)

【Leetcode 200】岛屿的数量

【Leetcode236】课程表

【Leetcode236】网络延迟时间

参考文献

【1】 Trees vs. Graphs - Open4Tech

相关推荐
嵌入式@秋刀鱼13 分钟前
《第四章-筋骨淬炼》 C++修炼生涯笔记(基础篇)数组与函数
开发语言·数据结构·c++·笔记·算法·链表·visual studio code
嵌入式@秋刀鱼16 分钟前
《第五章-心法进阶》 C++修炼生涯笔记(基础篇)指针与结构体⭐⭐⭐⭐⭐
c语言·开发语言·数据结构·c++·笔记·算法·visual studio code
简简单单做算法26 分钟前
基于PSO粒子群优化的VMD-LSTM时间序列预测算法matlab仿真
算法·matlab·lstm·时间序列预测·pso·vmd-lstm·pso-vmd-lstm
无聊的小坏坏32 分钟前
高精度算法详解:从原理到加减乘除的完整实现
算法
愚润求学36 分钟前
【递归、搜索与回溯】FloodFill算法(二)
c++·算法·leetcode
泽020237 分钟前
C++之list的自我实现
开发语言·数据结构·c++·算法·list
南枝异客1 小时前
四数之和-力扣
java·算法·leetcode
凌肖战1 小时前
C语言中提供的第三方库之哈希表实现
算法·哈希算法
lingling0092 小时前
迁移科技:破解纸箱拆垛场景的自动化升级密码
算法
Coding小公仔2 小时前
几种经典排序算法的C++实现
c++·算法·排序算法