543.Diameter_of_Binary_Tree

25 年 7 月 2 日 星期三
593 字
3 分钟

543. Diameter of Binary Tree

Screenshot 2026-03-07 at 11.09.28 am
Screenshot 2026-03-07 at 11.10.20 am

起始点和终点在叶子节点上,如果不在叶子节点上可以向叶子节点延伸。

枚举每个点,假设直径会在这个点拐弯

Screenshot 2026-03-07 at 11.12.26 am
js
var diameterOfBinaryTree = function (root) {
  // 初始化最大直径为 0,用于在递归过程中记录全局最大值
  let ans = 0

  /**
   * 深度优先搜索(DFS)函数,用于计算以当前节点为根的子树的最大链长
   * 同时在递归过程中更新全局最大直径
   * @param {TreeNode} node - 当前遍历的节点
   * @returns {number} - 以当前节点为端点的最大链长(边数)
   */
  function dfs(node) {
    // 递归终止条件:如果节点为空,返回 -1
    // 为什么返回 -1?因为叶子节点的子节点为空,叶子节点到空节点的边数为 0
    // 叶子节点的左/右链长 = dfs(null) + 1 = -1 + 1 = 0,符合实际意义
    if (node === null) {
      return -1
    }

    // 递归计算左子树的最大链长(当前节点到左子树最深节点的边数)
    // +1 是因为要加上当前节点到左子节点的这条边
    const lLen = dfs(node.left) + 1

    // 递归计算右子树的最大链长(当前节点到右子树最深节点的边数)
    // +1 是因为要加上当前节点到右子节点的这条边
    const rLen = dfs(node.right) + 1

    // 关键逻辑:以当前节点为转折点的路径长度 = 左链长 + 右链长
    // 用这个值更新全局最大直径 ans
    ans = Math.max(ans, lLen + rLen)

    // 返回以当前节点为端点的最大链长(供父节点计算使用)
    // 父节点只能选择左/右中更长的一条链,所以返回两者的最大值
    return Math.max(lLen, rLen)
  }

  // 从根节点开始执行深度优先搜索
  dfs(root)

  // 返回最终计算出的二叉树直径
  return ans
}

下面这种做法也可以

js
/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var diameterOfBinaryTree = function (root) {
  let ans = 0
  function dfs(root) {
    if (!root) {
      return 0
    }
    const rLen = dfs(root.right)
    const lLen = dfs(root.left)
    ans = Math.max(ans, rLen + lLen)
    return Math.max(rLen, lLen) + 1
  }
  dfs(root)
  return ans
}

文章标题:543.Diameter_of_Binary_Tree

文章作者:Sirui Chen

文章链接:https://blog.siruichen.me/posts/543diameter_of_binary_tree[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。