题解 | #二叉树的直径#

二叉树的直径

http://www.nowcoder.com/practice/15f977cedc5a4ffa8f03a3433d18650d

题目分析

  1. 题目给出我们一棵树的根节点
  2. 题目要求我们返回这棵树的最大的直径,其中直径定义为,树上任意两个叶子节点路径长度的最大值

方法一:(双重递归)递归确定深度+递归确定直径

  • 实现思路
    • 我们用两个递归函数来得到最终的最长直径结果
    • 递归函数一depth
      • 目标:获取当前节点的深度
      • 返回条件:当前节点为空None时返回深度为0
      • 递归主体:递归左子树获取其深度l,递归右子树获取其高度r,因此当前节点的深度为max(l,r)+1
    • 递归函数二diameterOfBinaryTree
      • 目标:获得当前节点为根的树中最大直径

      • 返回条件:当前节点为空None时返回树中最大直径为0

      • 递归主体:根据左子树右子树深度来确定通过当前节点的路径最大直径为d,返回d, 递归左子树的结果,递归右子树的结果三者中最大的值为最终目标

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return int整型
#
class Solution:
    def depth(self, node):
        if not node:
            return 0
        l = self.depth(node.left)            # 左子树的深度
        r = self.depth(node.right)           # 右子树的深度
        return max(l,r) + 1                  # 当前节点的深度
        
    def diameterOfBinaryTree(self , root: TreeNode) -> int:
        # write code here
        if not root:
            return 0
        d = self.depth(root.left) + self.depth(root.right)    # 通过当前节点本身的直径
        return max(d, self.diameterOfBinaryTree(root.left), self.diameterOfBinaryTree(root.right)) # 返回三者之一 

复杂度分析

  • 时间复杂度:O(n2)O(n^2),其中nn是树中节点数量。对于某个节点,算法在计算直径时访问一次节点,并且同时要访问其对应的整棵子树来计算高度,子树中所有的节点又被访问了一次,因此最终代价为平方级别的
  • 空间复杂度:O(height)O(height),其中heightheight是树的高度,递归深度和树高成线性关系

方法二:递归深度+直径实时记录

  • 实现思路
    • 根据方法一,我们只保留递归计算树中节点深度的递归函数。
    • 在每次计算出来当前节点的深度时,我们同时拿到了其左子树和右子树的深度
    • 此时就已经可以计算通过当前节点所对应的直径长度了,我们将其存储在ans
    • 最终返回ans即可

alt

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return int整型
#
class Solution:
    def diameterOfBinaryTree(self , root: TreeNode) -> int:
        # write code here
        self.ans = 0								# 最终结果
        def depth(node):
            if node == None:
                return 0
            l = depth(node.left)					# 左子树深度
            r = depth(node.right)					# 右子树深度
            self.ans = max(self.ans, l + r)			# 记录直径最大值
            return max(l, r) + 1					# 返回深度
        
        depth(root)
        return self.ans

复杂度分析

  • 时间复杂度:O(n)O(n),所有的节点都被遍历一次,因此时间代价和节点数量呈线性关系
  • 空间复杂度:O(height)O(height),其中heightheight为树高,递归深度和树高呈线性关系
全部评论

相关推荐

10-21 00:37
已编辑
门头沟学院 C++
小浪_Coding:你问别人,本来就是有求于人,别人肯定没有义务免费回答你丫, 有点流量每天私信可能都十几,几十条的,大家都有工作和自己的事情, 付费也是正常的, 就像你请别人搭把手, 总得给人家买瓶水喝吧
点赞 评论 收藏
分享
10-19 10:28
已编辑
成都理工大学 后端工程师
团孝子已上线feeling:面了很多家公司,能感受到目前只有小公司+外包喜欢问八股。大厂虽然也问八股,但是是从实习、项目中进行提问,并且大厂会问很深,面试官也会对你的回答进行思考➕追问,所以准备大厂面试前一定要备好相关资料。对于算法,我做的是codetop前100+力扣hot100+力扣高频150,面试中实感hot100就足够,基本上只要是hot100就秒答。对于项目和八股,我做的也是烂大街的星球项目,八股则是看小林和问ai,自己也写了很多技术博客和画了很多思维导图,并且自己也尝试用嘴巴说出来,不只停留于纸面。运气也很重要,必须要让面试官/HR看到简历才行,所以建议投递时间是下午两点。tl:第一岗位9.9 投递9.10 一面(一面评价:最近见过最强的大三,结束五分钟后约二面,都晚上九点了不下班吗)9.11 二面(三道算法a出两道,反问评价:经验不够等横向,我实习生要啥经验)9.21挂(实习时间过短+其他原因,想要一年实习的,为什么不招个正职)第二岗位10.10投递10.11约面(主管打电话,说看到我之前投递记录了想要我挂qa职进去干后端,同意)10.14 一面(无八股,主动说确实很强,意愿很强)10.16 oc其余,友邦,东软,东华,惠择,用友oc已拒京东测开一面挂(投后端被测开捞)腾讯测试已拒(投后端被测开捞)ps:表扬惠择的主管面,没怎么问技术(可能是一面面试官沟通过了),全程一起讲大道理,解答了心中很多疑惑,也告诉我以面试官角度来看怎么选候选人,如果可以下次一定选惠择
HeaoDng:美团好像可以触发一面通
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务