【算法】 二叉树的直径

87 阅读2分钟

难度:简单

题目:

给你一棵二叉树的根节点,返回该树的 直径

二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root

两节点之间路径的 长度 由它们之间边数表示。

示例 1:

输入:root = [1,2,3,4,5]
输出:3
解释:3 ,取路径 [4,2,1,3][5,2,1,3] 的长度。

示例 2:

输入:root = [1,2]
输出:1

提示:

  • 树中节点数目在范围 [1, 104]
  • -100 <= Node.val <= 100

解题思路:

二叉树的直径是指树中任意两个节点之间的最长路径。这个问题可以通过深度优先搜索(DFS)来解决,同时在遍历过程中计算每个节点的左右子树高度,进而确定最长路径。

  1. 定义递归函数:定义一个递归函数 getHeightAndDiameter(node),该函数返回一个对象,包含两个属性:height(节点的最大高度)和 diameter(以该节点为根的子树的直径)。
  2. 基本情况:如果当前节点 node 为空,返回 { height: 0, diameter: 0 }
  3. 递归调用:分别计算左右子树的 heightdiameter
  4. 计算当前节点的直径:当前节点的直径是其左右子树高度之和。这是因为最长路径可能是从左子树的一个节点到右子树的另一个节点。
  5. 更新全局直径:在遍历过程中,维护一个全局变量来记录遇到的最长直径。
  6. 返回结果:返回当前节点的 heightdiameter

JavaScript代码实现:

/**
 * 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 maxDiameter = 0;

    function getHeightAndDiameter(node) {
        if (node === null) {
            return { height: 0, diameter: 0 };
        }
        
        const left = getHeightAndDiameter(node.left);
        const right = getHeightAndDiameter(node.right);
        
        // 当前节点的直径是左右子树的高度之和
        const currentDiameter = left.height + right.height;
        maxDiameter = Math.max(maxDiameter, currentDiameter);
        
        // 当前节点的高度是左右子树中较高者加一
        const currentHeight = Math.max(left.height, right.height) + 1;
        
        return { height: currentHeight, diameter: maxDiameter };
    }
    
    getHeightAndDiameter(root);
    return maxDiameter;
};