【LeetCode 热题100】深入理解二叉树结构变化与路径特性(力扣104 / 226 / 114 / 543)(Go语言版)

简介: 本博客深入探讨二叉树的深度计算、结构变换与路径分析,涵盖四道经典题目:104(最大深度)、226(翻转二叉树)、114(展开为链表)和543(二叉树直径)。通过递归与遍历策略(前序、后序等),解析每题的核心思路与实现方法。结合代码示例(Go语言),帮助读者掌握二叉树相关算法的精髓。下一讲将聚焦二叉树构造问题,欢迎持续关注!

🌲 深入理解二叉树结构变化与路径特性(力扣104 / 226 / 114 / 543)

在解题过程中,我们不仅要掌握二叉树的遍历方法,还需要理解它的结构特性。本篇博客将围绕二叉树的 深度计算、结构变换与路径分析 展开,涉及以下四道高频题:

  • [x] 104. 二叉树的最大深度
  • [x] 226. 翻转二叉树
  • [x] 114. 二叉树展开为链表
  • [x] 543. 二叉树的直径

📌 104. 二叉树的最大深度

✅ 题目描述:

给定一棵二叉树,找出其最大深度。最大深度是从根节点到最远叶子节点的最长路径上的节点数。

💡 解题思路:

这是一道非常经典的递归题。最大深度 = 左子树最大深度 与 右子树最大深度中的较大者 + 1。

我们可以使用 后序遍历(DFS),从叶子节点向上递归:

🧠 步骤解析:

  1. 递归终止条件:节点为空,返回0。
  2. 分别递归计算左右子树的最大深度。
  3. 当前节点的最大深度 = max(左,右) + 1。

💻 Go 实现:

func maxDepth(root *TreeNode) int {
   
    if root == nil {
   
        return 0
    }
    left := maxDepth(root.Left)
    right := maxDepth(root.Right)
    return max(left, right) + 1
}

📌 226. 翻转二叉树

✅ 题目描述:

翻转一棵二叉树,即左右子树交换。

示例:

输入:     4
         / \
        2   7
       / \ / \
      1  3 6  9
输出:     4
         / \
        7   2
       / \ / \
      9  6 3  1

💡 解题思路:

本质是递归地交换左右子树,可以用前序遍历来交换每个节点的左右子树。

🧠 步骤解析:

  1. 如果当前节点为 nil,返回 nil。
  2. 递归翻转左右子树。
  3. 交换左右子树。

💻 Go 实现:

func invertTree(root *TreeNode) *TreeNode {
   
    if root == nil {
   
        return nil
    }
    root.Left, root.Right = invertTree(root.Right), invertTree(root.Left)
    return root
}

📌 114. 二叉树展开为链表

✅ 题目描述:

将二叉树原地展开为一个单链表,使用前序遍历顺序,即所有右指针指向下一个节点,左指针置空。

💡 解题思路:

需要在原地修改树结构,我们可以借助 后序遍历 反向处理。

  • 倒着处理每个节点,将右子树先展开,再左子树展开,然后将当前节点的右指针指向上一个访问节点(类似于链表的前插操作)。

🧠 步骤解析(后序遍历 + 记录上一个节点):

  1. 先递归右子树,再递归左子树。
  2. 每次处理当前节点时,将其右指针指向前一个访问的节点(pre),左指针置空。
  3. 更新 pre 为当前节点。

💻 Go 实现:

var prev *TreeNode

func flatten(root *TreeNode) {
   
    if root == nil {
   
        return
    }
    flatten(root.Right)
    flatten(root.Left)
    root.Right = prev
    root.Left = nil
    prev = root
}

📌 543. 二叉树的直径

✅ 题目描述:

给定一棵二叉树,计算它的直径。直径是任意两个节点之间的最长路径,路径长度是节点数之差。

💡 解题思路:

路径可能穿过某个节点的左右子树,因此我们可以在计算深度时顺便计算当前节点左右深度之和,并维护最大值。

🧠 步骤解析(递归 + 回溯):

  1. 定义一个全局变量 res,记录最长路径。
  2. 在递归函数中,分别计算左右子树深度。
  3. 更新 res = max(res, left + right)
  4. 每次返回左右子树中最大深度 + 1。

💻 Go 实现:

var res int

func diameterOfBinaryTree(root *TreeNode) int {
   
    res = 0
    dfs(root)
    return res
}

func dfs(root *TreeNode) int {
   
    if root == nil {
   
        return 0
    }
    left := dfs(root.Left)
    right := dfs(root.Right)
    res = max(res, left+right)
    return max(left, right) + 1
}

🧠 小结与思考

题号 关键词 思维方法 特点
104 最大深度 后序遍历 求树高的典型题目
226 翻转结构 前序递归 每层交换左右子树
114 展开链表 后序遍历 倒序拼接前序路径
543 最大路径 递归+回溯 求路径最大值

📌 总结

  • 熟练掌握递归遍历策略(前序、中序、后序),在结构变化题中尤为重要。
  • 遇到路径相关问题时,可结合深度计算回溯策略
  • 在链表化或结构修改题目中,注意是否需要原地修改、是否可以使用辅助变量。

✍️ 下一篇我们将讨论“二叉树的构造”相关问题(105 & 108),包括如何根据前序中序构造树,以及如何构造平衡 BST。敬请期待!

如果这篇文章对你有帮助,欢迎点赞 👍、收藏 ⭐、关注 💻!持续更新 LeetCode 高频题详解 🚀🌲

目录
相关文章
|
6月前
|
Go
【LeetCode 热题100】DP 实战进阶:最长递增子序列、乘积最大子数组、分割等和子集(力扣300 / 152/ 416 )(Go语言版)
本文深入解析三道经典的动态规划问题:**最长递增子序列(LIS)**、**乘积最大子数组** 和 **分割等和子集**。 - **300. LIS** 通过 `dp[i]` 表示以第 `i` 个元素结尾的最长递增子序列长度,支持 O(n²) 动态规划与 O(n log n) 的二分优化。 - **152. 乘积最大子数组** 利用正负数特性,同时维护最大值与最小值的状态转移方程。 - **416. 分割等和子集** 转化为 0-1 背包问题,通过布尔型 DP 实现子集和判断。 总结对比了三题的状态定义与解法技巧,并延伸至相关变种问题,助你掌握动态规划的核心思想与灵活应用!
286 1
|
6月前
|
分布式计算 算法 Go
【LeetCode 热题100】BFS/DFS 实战:岛屿数量 & 腐烂的橘子(力扣200 / 994 )(Go语言版)
本文讲解了两道经典的图论问题:**岛屿数量(LeetCode 200)** 和 **腐烂的橘子(LeetCode 994)**,分别通过 DFS/BFS 实现。在“岛屿数量”中,利用深度或广度优先搜索遍历二维网格,标记连通陆地并计数;“腐烂的橘子”则采用多源 BFS,模拟腐烂传播过程,计算最短时间。两者均需掌握访问标记技巧,是学习网格搜索算法的绝佳实践。
282 1
|
6月前
|
Go
【LeetCode 热题100】BFS/DFS 实战:岛屿数量 & 腐烂的橘子(力扣200 / 994 )(Go语言版)
本篇博客详细解析了三道经典的动态规划问题:198. 打家劫舍(线性状态转移)、279. 完全平方数与322. 零钱兑换(完全背包问题)。通过 Go 语言实现,帮助读者掌握动态规划的核心思想及其实战技巧。从状态定义到转移方程,逐步剖析每道题的解法,并总结其异同点,助力解决更复杂的 DP 问题。适合初学者深入理解动态规划的应用场景和优化方法。
221 0
|
6月前
|
算法 Go 索引
【LeetCode 热题100】回溯:括号生成 & 组合总和(力扣22 / 39 )(Go语言版)
本文深入解析了LeetCode上的两道经典回溯算法题:**22. 括号生成**与**39. 组合总和**。括号生成通过维护左右括号数量,确保路径合法并构造有效组合;组合总和则允许元素重复选择,利用剪枝优化搜索空间以找到所有满足目标和的组合。两者均需明确路径、选择列表及结束条件,同时合理运用剪枝策略提升效率。文章附有Go语言实现代码,助你掌握回溯算法的核心思想。
257 0
|
2月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
206 1
|
10月前
|
运维 监控 算法
监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。
|
4月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
299 1
|
4月前
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
401 0
|
4月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
261 0
|
4月前
|
Cloud Native Java 中间件
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
230 0