跳到主要内容

543. 二叉树的直径

题目描述

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

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

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

示例 1

示例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

出处LeetCode

解法一:递归

思路

递归遍历二叉树,计算每个节点的左右子树的高度之和。

实现

function diameterOfBinaryTree(root: TreeNode | null): number {
let diameter = 0;
const dfs = (node: TreeNode | null): number => {
if (node === null) {
return 0;
}
const left = dfs(node.left);
const right = dfs(node.right);
diameter = Math.max(diameter, left + right);
return Math.max(left, right) + 1;
};
dfs(root);
return diameter;
}

复杂度分析

  • 时间复杂度:O(n)O(n),其中 n 是二叉树的节点数。每个节点在递归中只被遍历一次。
  • 空间复杂度:O(n)O(n),其中 n 是二叉树的节点数。递归函数的调用栈的深度等于二叉树的高度,最坏情况下二叉树的高度等于节点数。

解法二:迭代

思路

迭代遍历二叉树,计算每个节点的左右子树的高度之和。

实现

function diameterOfBinaryTree(root: TreeNode | null): number {
let diameter = 0;
const stack: TreeNode[] = [];
const map = new Map<TreeNode, number>();
let prev: TreeNode | null = null;
let node = root;
while (node || stack.length) {
while (node) {
stack.push(node);
node = node.left;
}
node = stack[stack.length - 1];
if (node.right && node.right !== prev) {
node = node.right;
} else {
const left = map.get(node.left) ?? 0;
const right = map.get(node.right) ?? 0;
diameter = Math.max(diameter, left + right);
map.set(node, Math.max(left, right) + 1);
prev = node;
stack.pop();
node = null;
}
}
return diameter;
}

复杂度分析

  • 时间复杂度:O(n)O(n),其中 n 是二叉树的节点数。每个节点在迭代中只被遍历一次。
  • 空间复杂度:O(n)O(n),其中 n 是二叉树的节点数。栈的深度等于二叉树的高度,最坏情况下二叉树的高度等于节点数。