题目描述
题目分析
所谓求直径,就是求左右子树深度之和,而这个题又不能仅仅是考虑左右子树的而深度之和,因为求直径的时候可以不经过根结点。也就意味着如果root结点的右子树只有一层,而左子树却长满了结点,直接求root结点两子树的深度之和就错了。
下面是我想的一个比较暴力的方法:首先遍历二叉树,把所有的内部结点都用数组保存(因为叶结点的直径为0),后面对每个结点求直径,返回最大值。
class Solution {
public:
vector<TreeNode*> nodes;
int getDepth(TreeNode* root){
if(root == NULL) return 0;
int l_depth = getDepth(root->left);
int r_depth = getDepth(root->right);
return l_depth > r_depth ? l_depth+1 : r_depth+1;
}
void Traverse(TreeNode* root){
if(root == NULL) return ;
Traverse(root->left);
if(root->left || root->right) nodes.push_back(root);//不要叶子结点
Traverse(root->right);
}
int diameterOfBinaryTree(TreeNode* root) {
if(root == NULL) return 0;
if(root->left == NULL && root->right == NULL) return 0;//只有root结点
Traverse(root);
int res = INT_MIN;
for(TreeNode* node : nodes){
int cur_depth = getDepth(node->left) + getDepth(node->right);
res = res > cur_depth ? res : cur_depth;
}
return res;
}
};
当然,效率不高,还占用额外空间。下面是翻看题解后写出来的
- 遍历的时候就可以计算直径,用全局变量保存
- 最后返回该全局变量即可
class Solution {
public:
int diameter = 0;
int countDiameter(TreeNode* root){
if(root == NULL) return 0;
int l_depth = countDiameter(root->left);
int r_depth = countDiameter(root->right);
diameter = max(diameter , l_depth + r_depth);
return max(l_depth , r_depth) + 1;
}
int diameterOfBinaryTree(TreeNode* root) {
countDiameter(root);
return diameter;
}
};