题目地址:力扣
这道题我觉得官方题解有点难懂,反而是我自己的思路更好想明白这个问题。根据题目定义,某个根节点二叉树的直径实际上就是其左子树的深度加上右子树深度之和,因此求深度的问题很容易想到使用DFS递归。但是呢,问题在于二叉树的最大直径并非是一定经过根节点的,因此所有节点都有机会得到最大的直径,所以我们可以设置一个全局的最大直径并不断对其进行更新。
接着我们需要想清楚我们求高度的函数height()需要做什么,首先由于其是一个递归函数因此要有终止条件对于一个叶子结点来说,它没有左孩子也没有右孩子正好适合我们终止递归,因此我们的递归最深就是到叶子节点。那么对于一个非叶子节点来说,我们需要求其左子树的深度,因此需要递归的调用height()函数,我们也需要求其右子树的深度,也需要递归调用height()函数。对于一个任意节点来说,我们还需要将其直径与全局最大进行比较,因此需要比较左子树深度加右子树深度与全局最大直径的值。最后这个函数做完了直径更新之后,由于当前节点是其上层节点的左孩子或右孩子,因此需要返回其深度。
这样我们就完成了递归函数的设计,那么最外层函数调用递归函数,但是最外层函数并不需要用到其返回值,而是只需要全局最大直径就可以了,因此在调用的时候可以不管它的返回值。
class Solution {
public:
// 全局的最大直径
int maxLength;
int height(TreeNode *root)
{
// 左子树深度和右子树深度
int lheight, rheight;
// 若左孩子非空,左子树深度等于左孩子求深度再加1
if (root->left != nullptr)
lheight = height(root->left) + 1;
// 左孩子空深度为0
else
lheight = 0;
// 若右孩子非空,右子树深度等于右孩子求深度再加1
if (root->right != nullptr)
rheight = height(root->right) + 1;
// 右孩子空深度为0
else
rheight = 0;
// 更新全局最大直径
if (lheight + rheight > maxLength)
maxLength = lheight + rheight;
// 将当前节点深度(其左子树深度和右子树深度最大值)返回给上一层
return max(lheight, rheight);
}
int diameterOfBinaryTree(TreeNode* root) {
maxLength = 0;
// 不需要接受递归函数的返回值
height(root);
return maxLength;
}
};
Accepted
- 104/104 cases passed (12 ms)
- Your runtime beats 41.16 % of cpp submissions
- Your memory usage beats 57.31 % of cpp submissions (19.7 MB)