心路历程:
这道题如果题干中不说这条路径可能不经过root的话,可能这道题就是个中等难度题了。思考二叉树问题:如何在递归遍历中解决问题,如何转化为已有的问题。
这道题的特殊之处在于需要对二叉树进行两次的遍历,第一次遍历计算以node结点为根到其叶子结点的最大路径长度,第二次遍历计算以node为根节点的左右子树最大长度的和+2。
注意的点:
1、求的是路径的长度,注意要在结点的数量上减一
2、第二次遍历时记得+2代表该根节点到左右两个子树的距离和
3、二叉树node遍历加上cache装饰器会更快
解法:先后两次dfs遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
@cache
def dfs1(node): # node结点为根节点到叶子结点的路径数
if not node: return -1 # 这里-1是为了将结点数转化为边的数量
return max(dfs1(node.left), dfs1(node.right)) + 1
maxlen = 0
@cache
def dfs2(node): # 遍历二叉树
nonlocal maxlen
if not node: return
leftmax = dfs1(node.left)
rightmax = dfs1(node.right)
maxlen = max(maxlen, 2 + leftmax + rightmax)
dfs2(node.left)
dfs2(node.right)
dfs2(root)
return maxlen