【算法训练-二叉树 三】【最大深度与直径】求二叉树的最大深度、求二叉树的直径

简介: 【算法训练-二叉树 三】【最大深度与直径】求二叉树的最大深度、求二叉树的直径

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【求二叉树的直径】,使用【二叉树】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。

名曲目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍

求二叉树的最大深度【EASY】

求二叉树的最大深度

题干

解题思路

最大深度是所有叶子节点的深度的最大值,深度是指树的根节点到任一叶子节点路径上节点的数量,因此从根节点每次往下一层深度就会加1。因此二叉树的深度就等于根节点这个1层加上左子树和右子树深度的最大值

  1. 终止条件: 当进入叶子节点后,再进入子节点,即为空,没有深度可言,返回0.
  2. 返回值: 每一级按照上述公式,返回两边子树深度的最大值加上本级的深度,即加1.
  3. 本级任务: 每一级的任务就是进入左右子树,求左右子树的深度。

代码实现

给出代码实现基本档案

基本数据结构二叉树

辅助数据结构

算法递归、DFS

技巧

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;
/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @return int整型
     */
    public int maxDepth (TreeNode root) {
        // 1 如果只有根节点,返回1
        if (root == null) {
            return 0;
        }
        // 2 递归获取左子树最大深度
        int leftMaxLenth = maxDepth(root.left);
        // 3 递归获取右子树最大深度
        int rightMaxLenth = maxDepth(root.right);
        // 4 返回当前最大深度
        return Math.max(leftMaxLenth, rightMaxLenth) + 1;
    }
}

复杂度分析

时间复杂度:O(n),其中n为二叉树的节点数,遍历整棵二叉树

空间复杂度:O(n),最坏情况下,二叉树化为链表,递归栈深度最大为n

求二叉树的直径【EASY】

相对于求深度难度有所升级。

题干

解题思路

依据题意可以得出,直径最大应该是两个叶子节点之间的路径。首先我们知道一条路径的长度为该路径经过的节点数减一,所以求直径(即求路径长度的最大值)等效于求路径经过节点数的最大值减一任意一条路径均可以被看作由某个节点为起点,从其左儿子和右儿子向下遍历的路径拼接得到,也就是其两边子树最大深度之和,但需要注意的是,这个节点不一定是根节点,只是直径路径上两个节点的公共节点而已

所以问题就转换成了求两个叶子节点之间最大距离的公共节点

代码实现

给出代码实现基本档案

基本数据结构二叉树

辅助数据结构

算法迭代

技巧

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

private int maxNodeNum;
    public int diameterOfBinaryTree(TreeNode root) {
        // 1 处理异常情况
        if (root == null) {
            return 0;
        }
        // 2 初始途径节点设置为1
        maxNodeNum = 1;
        // 3 递归获取根节点最大深度,过程中求最大直径
        maxDepth(root);
        // 4 全部途径节点数-1为最终结果直径
        return maxNodeNum - 1;
    }
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @return int整型
     */
    public int maxDepth (TreeNode root) {
        // 1 如果只有根节点,返回1
        if (root == null) {
            return 0;
        }
        // 2 递归获取左子树最大深度
        int leftMaxLenth = maxDepth(root.left);
        // 3 递归获取右子树最大深度
        int rightMaxLenth = maxDepth(root.right);
        // 4 直径为左右最大深度和+1(要算上根节点)
        int curNodeNum = leftMaxLenth + rightMaxLenth + 1;
        maxNodeNum = Math.max(maxNodeNum, curNodeNum);
        return Math.max(leftMaxLenth, rightMaxLenth) + 1;
    }

复杂度分析

时间复杂度:遍历了整棵树节点,时间复杂度为O(N)

空间复杂度:极端情况下,二叉树退化为链表,递归栈的深度为O(N),空间复杂度为O(N)

拓展知识:二叉树的最大深度与直径

二叉树的直径和最大深度是树结构中两个不同但相关的概念。

  1. 最大深度(Maximum Depth):
    最大深度是指二叉树中从根节点到叶子节点的最长路径的长度。通常,可以使用递归算法来计算最大深度,如下所示的伪代码:
function maxDepth(node):
    if node is null:
        return 0
    leftDepth = maxDepth(node.left)
    rightDepth = maxDepth(node.right)
    return max(leftDepth, rightDepth) + 1
  1. 二叉树的直径(Diameter of a Binary Tree):
    二叉树的直径是指二叉树中任意两个节点之间的最长路径的长度这个路径不一定通过根节点。计算二叉树的直径通常需要通过递归来查找,可以使用以下方法:
function diameterOfBinaryTree(root):
    if root is null:
        return 0
    # 计算左子树的最大深度
    leftDepth = maxDepth(root.left)
    # 计算右子树的最大深度
    rightDepth = maxDepth(root.right)
    # 计算经过根节点的直径
    rootDiameter = leftDepth + rightDepth
    # 计算左子树的直径
    leftDiameter = diameterOfBinaryTree(root.left)
    # 计算右子树的直径
    rightDiameter = diameterOfBinaryTree(root.right)
    # 返回三者中的最大值
    return max(rootDiameter, leftDiameter, rightDiameter)

请注意,这个算法的时间复杂度较高,因为它在每个节点上都会多次计算最大深度。如果需要优化性能,可以使用动态规划或记忆化搜索来避免重复计算。

相关文章
|
2天前
|
存储 算法 Python
文件管理系统中基于 Python 语言的二叉树查找算法探秘
在数字化时代,文件管理系统至关重要。本文探讨了二叉树查找算法在文件管理中的应用,并通过Python代码展示了其实现过程。二叉树是一种非线性数据结构,每个节点最多有两个子节点。通过文件名的字典序构建和查找二叉树,能高效地管理和检索文件。相较于顺序查找,二叉树查找每次比较可排除一半子树,极大提升了查找效率,尤其适用于海量文件管理。Python代码示例包括定义节点类、插入和查找函数,展示了如何快速定位目标文件。二叉树查找算法为文件管理系统的优化提供了有效途径。
34 5
|
1月前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
1月前
|
存储 缓存 算法
如何提高二叉树遍历算法的效率?
选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
61 5
|
2月前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
蓝桥杯Python编程练习题的集合,涵盖了从基础到提高的多个算法题目及其解答。
127 3
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
|
1月前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
48 0
|
1月前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
2月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
32 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
2月前
|
存储 算法 搜索推荐
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
37 0
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
|
2天前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
105 80
|
21天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。