坚持刷题 | 二叉树的直径

news2024/9/22 5:14:37

文章目录

  • 题目
  • 考察点
  • 代码实现
  • 实现总结
  • 方便用迭代的方式实现吗?
    • 迭代实现
    • 迭代实现总结

Hello,大家好,我是阿月。坚持话题,老年痴呆追不上我,今天还有时间,那就再来一题吧:二叉树的直径

题目

543.二叉树的直径
在这里插入图片描述

考察点

  • 理解二叉树的结构和直径的定义。
  • 理解直径的定义,即任意两个节点之间最长路径的长度。
  • 能够利用数据结构合理的设计出递归算法并实现。
  • 算法的正确性和高效性是非常重要的考察点。

代码实现

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class BinaryTreeDiameter {
    int diameter;

    public int diameterOfBinaryTree(TreeNode root) {
        diameter = 0;
        depth(root);
        return diameter;
    }

    private int depth(TreeNode node) {
        if (node == null) return 0;

        int leftDepth = depth(node.left);
        int rightDepth = depth(node.right);

        diameter = Math.max(diameter, leftDepth + rightDepth);

        return Math.max(leftDepth, rightDepth) + 1;
    }

    public static void main(String[] args) {
        // 构建测试用的二叉树
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(5);

        BinaryTreeDiameter solution = new BinaryTreeDiameter();
        System.out.println("Diameter of the binary tree: " + solution.diameterOfBinaryTree(root));
    }
}

实现总结

  • 方法diameterOfBinaryTree,用来计算二叉树的直径。
  • depth方法被用来计算节点的深度,并通过计算左右子树的深度,更新直径的值。
  • 最后,在main方法中构建一个测试用的二叉树,并输出其直径。
  • 这个实现实际上借鉴了坚持刷题|二叉树的最大深度的思想。
    • 在计算二叉树的直径时,需要获取每个节点的左子树和右子树的深度,并结合起来计算直径。
    • 在计算二叉树的最大深度时,也是递归地计算左子树和右子树的深度,然后取最大值并加上根节点的深度来得到整棵树的深度。
  • 时间复杂度:O(N),其中 N是二叉树中节点的数量。
    • 在深度优先搜索(DFS)的过程中,遍历了二叉树的每个节点一次。
    • 对于每个节点,都需要计算其左子树和右子树的深度,这个操作的时间复杂度是 O(1) ,因为每个节点只需要常数时间来计算。
    • 因此,总的时间复杂度是所有节点的数量,即 O(N)。

方便用迭代的方式实现吗?

当涉及到计算二叉树直径时,通常更适合使用递归而不是迭代。尽管可以通过一些技巧来使用迭代,但通常会更加复杂且不直观。这是因为直径的计算涉及到节点的深度,而深度优先搜索(DFS)的自然实现是通过递归来完成的。

迭代实现

import java.util.Stack;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class BinaryTreeDiameterIterative {
    public int diameterOfBinaryTree(TreeNode root) {
        if (root == null) return 0;
        
        int diameter = 0;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            int leftDepth = maxDepth(node.left);
            int rightDepth = maxDepth(node.right);
            diameter = Math.max(diameter, leftDepth + rightDepth);
            
            if (node.left != null) stack.push(node.left);
            if (node.right != null) stack.push(node.right);
        }
        
        return diameter;
    }
    
    private int maxDepth(TreeNode node) {
        if (node == null) return 0;
        
        int leftDepth = 0, rightDepth = 0;
        Stack<TreeNode> nodeStack = new Stack<>();
        Stack<Integer> depthStack = new Stack<>();
        nodeStack.push(node);
        depthStack.push(1);
        
        while (!nodeStack.isEmpty()) {
            TreeNode currNode = nodeStack.pop();
            int currDepth = depthStack.pop();
            if (currNode.left != null) {
                nodeStack.push(currNode.left);
                depthStack.push(currDepth + 1);
            }
            if (currNode.right != null) {
                nodeStack.push(currNode.right);
                depthStack.push(currDepth + 1);
            }
            leftDepth = Math.max(leftDepth, currDepth);
        }
        
        return leftDepth;
    }

    public static void main(String[] args) {
        // 构建测试用的二叉树
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(5);

        BinaryTreeDiameterIterative solution = new BinaryTreeDiameterIterative();
        System.out.println("Diameter of the binary tree: " + solution.diameterOfBinaryTree(root));
    }
}

迭代实现总结

  • 这个迭代版本使用了两个栈来模拟深度优先搜索(DFS)。
  • 第一个栈用于遍历树的节点,第二个栈用于跟踪节点的深度。
  • 通过遍历树的节点,计算每个节点的左子树和右子树的深度,并更新直径的最大值。
  • 尽管迭代版本是可能的,但可以看出它通常会比递归版本更加复杂和难以理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1436736.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

子集枚举介绍

集合枚举的意思是从一个集合中找出它的所有子集。集合中每个元素都可以被选或不选&#xff0c;含有n个元素的集合总共有个子集&#xff08;包括全集和空集&#xff09; 例如考虑集合和它的4个子集、、、&#xff0c;按照某个顺序&#xff0c;把全集A中的每个元素在每个子集中的…

Visual Studio 2010+C#实现信源和信息熵

1. 设计要求 以图形界面的方式设计一套程序&#xff0c;该程序可以实现以下功能&#xff1a; 从输入框输入单个或多个概率&#xff0c;然后使用者可以通过相关按钮的点击求解相应的对数&#xff0c;自信息以及信息熵程序要能够实现马尔可夫信源转移概率矩阵的输入并且可以计算…

计算机网络-差错控制(纠错编码 海明码 纠错方法)

文章目录 纠错编码-海明码海明距离1.确定校验码位数r2.确定校验码和数据的位置3.求出校验码的值4.检错并纠错纠错方法1纠错方法2 小结 纠错编码-海明码 奇偶校验码&#xff1a;只能发现错误不能找到错误位置和纠正错误 海明距离 如果找到码距为1&#xff0c;那肯定为1了&…

鸿蒙开发-UI-组件导航-Tabs

鸿蒙开发-UI-组件 鸿蒙开发-UI-组件2 鸿蒙开发-UI-组件3 鸿蒙开发-UI-气泡/菜单 鸿蒙开发-UI-页面路由 鸿蒙开发-UI-组件导航-Navigation 文章目录 一、基本概念 二、导航 1.底部导航 2.顶部导航 3.侧边导航 4.导航栏限制滑动 三、导航栏 1.固定导航栏 2.滚动导航栏 3…

莉莉与神奇花朵的冒险

现在&#xff0c;我将根据这些步骤编写一个对话形式的童话故事。 在很久很久以前的一个小村庄里&#xff0c;有一个勤劳善良的小女孩叫莉莉。她住在一间小茅屋里&#xff0c;和她的奶奶一起生活。奶奶年纪大了&#xff0c;行动不便&#xff0c;所以莉莉每天都要照顾她。 一天&a…

【多模态大模型】跨越视觉-语言界限:BLIP的多任务精细处理策略

BLIP 核心思想MED架构和CapFilt方法效果 总结CLIP模型 VS BLIP模型CLIP模型BLIP模型 核心思想 论文&#xff1a;https://proceedings.mlr.press/v162/li22n/li22n.pdf 代码&#xff1a;https://github.com/salesforce/BLIP BLIP&#xff08;Bootstrapping Language-Image Pre…

win11安装MySql5.7

1、下载 打开下载链接&#xff1a;MySQL :: Download MySQL Installer 2、安装 2.1、安装界面 2.2、选择自定义安装 2.3、根据自己系统的位数进行选择是X64还是X86 2.4、选择安装路径 2.5、继续下一步 2.6、选择服务器专用&#xff0c;端口是3306 2.7、设置密码 2.8、设置服…

python函数入参、类成员引用支持灵活参数可配

一、背景 python编码时&#xff0c;有可能在不同场景下输入修改的参数&#xff0c;不方便直接写死&#xff0c;因此需要灵活配置这些函数入参&#xff0c;类成员 二、函数入参支持灵活可配 场景&#xff1a;如下场景&#xff0c;对于hello函数&#xff0c;不同场景下想要对不…

async/await使用过程中,要注意的问题

问: const getData async () >{ console.log(触发了getData接口) let resultData await getActivityInfo(activityId); console.log(resultData,resultData) let id resultData.id; let shareImg resultData.shareImg let shareSubtitle resultData.shareSubtit…

T-Sql 也能更新修改查询JSON?

今天看见一个澳洲项目里面使用了 JSON_VALUE 这样的函数解析 JSON 我倍感诧异&#xff0c;我印象当中Sql Server并不支持JOSN的相关操作&#xff0c;他最多只把JSON当成一个字符串来存储&#xff0c;更不要说去解析&#xff0c;查询和更新了 我随后查询了下此函数&#xff0c;…

美颜SDK是什么?探秘直播美颜SDK在视频社交平台中的应用

当今&#xff0c;美颜SDK正扮演着改变用户体验的“角色”&#xff0c;本篇文章&#xff0c;小编将为大家讲述美颜SDK的概念、原理以及在视频社交平台中的广泛应用。 一、什么是美颜SDK&#xff1f; 美颜SDK是一套软件工具包&#xff0c;提供了一系列美颜算法和功能&#xff…

基础面试题整理6之Redis

1.Redis的应用场景 Redis支持类型&#xff1a;String、hash、set、zset、list String类型 hash类型 set类型 zset类型 list类型 一般用作缓存&#xff0c;例如 如何同时操作同一功能 2.redis是单线程 Redis服务端(数据操作)是单线程&#xff0c;所以Redis是并发安全的,因…

页面模块向上渐变显示效果实现

ps: 先祝各位朋友新春快乐 ^o^/ 想要首页不那么枯燥无味吗&#xff1f;还在未首页过于单调而苦恼吧&#xff0c;来试试这个吧&#xff08;大佬请忽略上述语句o&#xff09; 今天要实现一个页面线上渐变显示的效果&#xff0c;用来丰富首页等页面&#xff1a; 这里先随机建立几…

哈希加密Python实现

一、代码 from cryptography.fernet import Fernet import os import bcrypt# 密钥管理和对称加密相关 def save_key_to_file(key: bytes, key_path: str):with open(key_path, wb) as file:file.write(key)def load_key_from_file(key_path: str) -> bytes:if not os.path…

linux服务器如何提高游戏帧率?

在Linux服务器上&#xff0c;由于硬件配置和系统的限制&#xff0c;提高游戏帧率变得更加困难。但是通过一些优化和调整&#xff0c;我们仍然可以提升Linux服务器上的游戏性能。 首先我们需要了解游戏帧率与服务器性能之间的关系。游戏帧率是指游戏每秒渲染的帧数&#xff0c;…

零基础学编程从哪里入手,在学习中可以线上会议答疑解惑

一、前言 零基础学编程可以先从容易学的语言入手&#xff0c;比如中文编程&#xff0c;然后再学其他编程语言则会比较轻松&#xff0c;初步掌握编程思路。很多IT人士一般学2到3种编程语言。 今天给大家分享的中文编程开发语言工具资料如下&#xff1a; 编程入门视频教程链接…

网络防御安全:2-6天笔记

第二章&#xff1a;防火墙 一、什么是防火墙 防火墙的主要职责在于&#xff1a;控制和防护。 防火墙可以根据安全策略来抓取流量之后做出对应的动作。 二、防火墙的发展 区域&#xff1a; Trust 区域&#xff0c;该区域内网络的受信任程度高&#xff0c;通常用来定义内部…

【cmu15445c++入门】(6)c++的迭代器

一、迭代器 C 迭代器是指向容器内元素的对象。它们可用于循环访问该容器的对象。我们知道迭代器的一个示例是指针。指针可用于循环访问 C 样式数组. 二、代码 自己实现一个迭代器 // C iterators are objects that point to an element inside a container. // They can be…

光学PCIe 6.0技术引领AI时代超大规模集群

随着云计算、大数据和人工智能技术的快速发展&#xff0c;超大规模数据中心正经历一场前所未有的变革。传统的集中式架构逐渐转变为解聚式&#xff08;disaggregated&#xff09;架构&#xff0c;这种架构将计算、存储和网络资源从单一的物理服务器中分离出来&#xff0c;形成独…

CSS实践调研,行业流行的CSS代码风格

案例1 Taro中的组件 以下为ScrollView组件的样式&#xff08;更新时间为2024年1月&#xff09;&#xff1a; taro的 image组件&#xff08;更新时间为3年前&#xff09;&#xff1a; 案例2&#xff1a; vantui 的Button组件 案例3&#xff1a;elementui的slider组件 案例4…