「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」
二叉树的直径(Diameter Of Binary Tree)
LeetCode传送门543. 二叉树的直径
原题
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
Given the root of a binary tree, return the length of the diameter of the tree.
The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root.
The length of a path between two nodes is represented by the number of edges between them.
Example:
Input: root = [1,2,3,4,5]
Output: 3
Explanation: 3 is the length of the path [4,2,1,3] or [5,2,1,3].
Input: root = [1,2]
Output: 1
Constraints:
-
The number of nodes in the tree is in the range .
-
-100 <= Node.val <= 100
思考线
解题思路
这道题,我是这样思考的,我们要找到它的直径,就要找到两个两个叶子节点中长度最大的值,这个值可以不经过根节点。 若两个叶子节点既然能相交,向上查找,肯定能找到他们共同的祖先元素。 而我们又只知道这棵二叉树的根节点。那么该如何求得结果呢? 假设直径经过根节点,那么直径的长度应该等于 根节点下的最长左子节点和最长右子节点组合而成的直径。 既然找到了根节点的最长直径,同理我们也可以找到根节点的左子节点 和右子节点的最长直径。 啊哈,这样我们可以用递归找到每一个节点的最长直径。 我们再在每个节点的最长直径中找最大的那个,不就找到这棵二叉树的最大直径了吗?
另外 在找最长直径的过程中,我们可以不用一直保存每个值,只需要比较已经得出的最大直径和当前直接的大小即可。 于是我们可以得到这样的的解
function diameterOfBinaryTree(root: TreeNode | null): number {
if (!root) return 0;
const res = { d: 0 }
const left = deep(root.left, res);
const right = deep(root.right, res);
return Math.max(res.d, left + right + 1) -1
};
function deep(root, res) {
if (!root) return 0;
const left = deep(root.left, res);
const right = deep(root.right, res);
res.d = Math.max(res.d, left + right + 1)
return Math.max(left, right) + 1;
}
时间复杂度
O(n), n 为二叉树的节点数.
这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。