题目来源 Leetcode,感谢🙇,如果内容对您有帮助,欢迎点赞!
题目描述
- 给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。
示例
- 给定二叉树
1
/ \
2 3
/ \
4 5
- 返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。
注意:两结点之间的路径长度是以它们之间边的数目表示。
解题思路
-
我们的目的是寻找在这个二叉树中任意两个节点路径长度的最大值。
-
任意一条路径均可以被看作由某个节点为起点,从其左右子树向下遍历的路径拼接得到。
-
下图中的路径
[9, 4, 2, 5, 7, 8]
,可以看作以 2 作为起点,从其左子树向下遍历的路径[2, 4, 9]
和 其右子树向下遍历的路径[2, 5, 7, 8]
拼接得到。
图片来源 leetcode -
假设我们给每个结点设置两个属性值
L
和R
分别代表它们左右子树的最大深度,那么我们的目标最大路径就是以左右子树最大深度和最大的那个节点为起点遍历左右子树最大深度的路径。那么路径长度也即直径为: d i a m e t e r = m a x ( L + R ) diameter = max(L + R) diameter=max(L+R) -
那我们接下就只需要遍历每一个节点,求出它们的
L
和R
即可,但简单分析我们就能知道父节点与左右子节点的L
和R
存在一定的递推关系。 L p a r e n t = m a x ( L l e f t N o d e , R l e f t N o d e ) + 1 R p a r e n t = m a x ( L r i g h t N o d e , R r i g h t N o d e ) + 1 L_{parent} = max(L_{leftNode} , R_{leftNode}) + 1\newline R_{parent} = max(L_{rightNode}, R_{rightNode}) + 1 Lparent=max(LleftNode,RleftNode)+1Rparent=max(LrightNode,RrightNode)+1 -
按照以上递推关系我们可以使用递归遍历(深度优先搜索DFS)整个二叉树,使用一个全局变量
diameter
保存最大的L
和R
之和,如果当前节点的L
和R
之和大于diameter
,则更新diameter
。
完整代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int diameter = 0;
int diameterOfBinaryTree(TreeNode* root) {
if(root == NULL) return 0;
dfs(root);
return diameter;
}
int dfs(TreeNode* node){
int L = 0;
int R = 0;
if(node->left != NULL){
L = dfs(node->left) + 1;
}
if(node->right != NULL){
R = dfs(node->right) + 1;
}
if(L + R > diameter){
diameter = L + R;
}
return max(L, R);
}
};
执行结果
Leetcode判题有时候不太稳定,同样的代码有时执行时间会变化😂