LeetCode二叉树的直径
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
示例 :
给定二叉树
1
/ \
2 3
/ \
4 5
返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。
思路:
这道题需要我们求二叉树的“直径”,其实不是特别的好求。但是原来我们求过二叉树的“深度”,我们可以利用“深度”求直径。这也是我在写这个题解的时候刚刚发现两者的关联,还是比较有趣的:
我们先来回顾一下求深度的代码,非常简单:
class Solution(object):
def maxDepth(self, root):
if not root:return 0#base case
#将左右节点送入递归
return max(self.maxDepth(root.left)+1,self.maxDepth(root.right)+1)
上面我们用了一个递归函数来求二叉树的深度,现在求二叉树的直径,我们依然可以用这个函数!我们发现,对于每一个节点也都可以算出“以该节点为顶峰时”二叉树的直径。那么我们只需要对每个节点都求一个直径,取最大值就可以得到最终结果了。
那么我们如何用求深度的函数来求直径呢?很简单:每个节点对应的直径就等于该节点左子树的深度+右子树的深度。
所以我们只需要在原来求最大深度的代码上加一点修改,便有:
class Solution(object):
def diameterOfBinaryTree(self, root):
maxx=[0]#在递归之外定义全局变量,遍历每个节点时都更新这个全局变量
def maxdepth(root):
if not root:return 0
'''在每个结点中去判断左子树+右子树的高度是否大于self.max,更新最大值
就多加了下面这句代码:
'''
maxx[0] = max(maxx[0], maxdepth(root.left)+maxdepth(root.right))
return max(maxdepth(root.left), maxdepth(root.right)) + 1
maxdepth(root)#调用一下递归函数
return maxx[0]#递归函数调用结束,全局变量也更新完了,返回
上面这段代码从逻辑上就已经可以实现我们求二叉树直径的功能了,然而,上面这个代码只是最大程度为了和第一段代码保持一致。但和明显我们无论是maxdepth(root.left)还是maxdepth(root.right)都写了两次,我们知道每个递归操作都具有很高的复杂度(因为它会递归到底),所以这么写肯定是极大地冗余和浪费的。我们把递归写在外面,把结果提前存起来,只需要写一次即可。
最终代码:
class Solution(object):
def diameterOfBinaryTree(self, root):
maxx=[0]#最终结果,存储最大直径,把它写成全局变量
def depth(root):
if not root:return 0
l = depth(root.left)#我们把left和right的结果先得出存起来
r = depth(root.right)
'''每个结点都要去判断左子树+右子树的高度是否大于self.max,更新最大值'''
maxx[0] = max(maxx[0], l+r)#更新全局变量
# 返回的是高度
return max(l, r) + 1
depth(root)
return maxx[0]
小结:
这道题我们从求二叉树的深度逐步引出了利用深度求直径的方法,最终给出最优写法。基本上只需要加上一个全局变量,然后利用深度和直径的关系就可以计算每个节点对应的深度,从而更新全局变量得到最终结果了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了