每日一题——二叉树的直径

二叉树的直径

    • 问题描述
      • 示例
        • 示例 1
        • 示例 2
      • 提示
    • 问题分析
    • 算法设计
    • 代码实现
    • 复杂度分析
    • 测试用例
      • 测试用例 1
      • 测试用例 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, 10^4]
  • -100 <= Node.val <= 100

问题分析

二叉树的直径是一个经典的树形结构问题。我们需要找到树中任意两个节点之间的最长路径。根据二叉树的性质,最长路径可以通过以下方式计算:

  • 对于每个节点,其直径等于左子树高度 + 右子树高度。
  • 遍历整棵树,找到所有节点的直径的最大值。

算法设计

为了高效计算二叉树的直径,我们采用**深度优先搜索(DFS)**的方法。具体步骤如下:

  1. 定义辅助函数 getHeight

    • 该函数用于计算子树的高度,并在递归过程中更新全局的最大直径。
    • 参数 maxDiameter 是一个指针,用于在递归过程中传递和更新最大直径的值。
  2. 递归计算子树高度

    • 对于每个节点,递归计算其左子树和右子树的高度。
    • 更新当前节点的直径:左子树高度 + 右子树高度
    • 更新全局的最大直径。
  3. 返回子树高度

    • 返回当前子树的高度:max(左子树高度, 右子树高度) + 1
  4. 主函数 diameterOfBinaryTree

    • 初始化最大直径为 0。
    • 调用辅助函数 getHeight,计算整棵树的最大直径。
    • 返回最大直径。

代码实现

以下是完整的 C 语言代码实现:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

// 定义一个辅助函数,用于计算子树的高度,并更新全局的最大直径
int getHeight(struct TreeNode* root, int* maxDiameter) {
    if (root == NULL) {
        return 0; // 空树的高度为0
    }
    // 递归计算左子树和右子树的高度
    int leftHeight = getHeight(root->left, maxDiameter);
    int rightHeight = getHeight(root->right, maxDiameter);

    // 更新最大直径
    *maxDiameter = (*maxDiameter > leftHeight + rightHeight) ? *maxDiameter : leftHeight + rightHeight;

    // 返回当前子树的高度
    return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}

int diameterOfBinaryTree(struct TreeNode* root) {
    if (root == NULL) {
        return 0; // 空树的直径为0
    }
    int maxDiameter = 0; // 用于存储最大直径
    getHeight(root, &maxDiameter); // 调用辅助函数计算直径
    return maxDiameter; // 返回最大直径
}

复杂度分析

  • 时间复杂度:(O(n)),其中 (n) 是树中节点的数量。每个节点只被访问一次。
  • 空间复杂度:(O(h)),其中 (h) 是树的高度。递归调用栈的深度最多为树的高度。

测试用例

测试用例 1

输入:root = [1,2,3,4,5]
输出:3
解释:最长路径的长度为 3,例如路径 [4,2,1,3][5,2,1,3]

测试用例 2

输入:root = [1,2]
输出:1
解释:最长路径的长度为 1,即路径 [2,1]

总结

通过深度优先搜索(DFS)的方法,我们可以在一次遍历中同时计算子树的高度和直径,从而高效地解决二叉树的直径问题。这种方法避免了重复计算,时间复杂度为 (O(n)),空间复杂度为 (O(h))。

你可能感兴趣的:(面经,算法题,C语言,数据结构,算法,leetcode)