给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。
示例 :
给定二叉树
1
/
2 3
/
4 5
返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。
注意:两结点之间的路径长度是以它们之间边的数目表示。
链接:https://leetcode-cn.com/problems/diameter-of-binary-tree
两个递归函数
转换一种角度来看,是不是其实就是根结点1的左右两个子树的深度之和呢。
那么我们只要对每一个结点求出其左右子树深度之和,这个值作为一个候选值,然后再对左右子结点分别调用求直径对递归函数,这三个值相互比较,取最大的值更新结果max,因为直径不一定会经过根结点,所以才要对左右子结点再分别算一次。
为了减少重复计算,我们用哈希表建立每个结点和其深度之间的映射,这样某个结点的深度之前计算过了,就不用再次计算了,参见代码如下:
c++
class Solution {
public:
int diameterOfBinaryTree(TreeNode* root) {
if (!root) return 0;
int max = getHeight(root->left) + getHeight(root->right);
return max(max, max(diameterOfBinaryTree(root->left), diameterOfBinaryTree(root->right)));
}
int getHeight(TreeNode* node) {
if (!node) return 0;
if (m.count(node)) return m[node];
int h = 1 + max(getHeight(node->left), getHeight(node->right));
return m[node] = h;
}
private:
unordered_map<TreeNode*, int> m;
};
一个递归函数
用max = 0来初始化这个值
在每次获得一个节点的左子树和右子树的值的时候,都需要比较一下max和左子树高度+右子树高度的大小,把更大的保存下来
然后如何求左子树和右子树的高度呢,那就是经典的递归求高度问题:max(maxDepth(root.left), maxDepth(root.right))+1
作者:sammy-4
链接:https://leetcode-cn.com/problems/diameter-of-binary-tree/solution/hot-100-9er-cha-shu-de-zhi-jing-python3-di-gui-ye-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
c++
class Solution {
public:
int diameterOfBinaryTree(TreeNode* root) {
int max = 0;
maxDepth(root, max);
return max;
}
int maxDepth(TreeNode* node, int& max) {
if (!node) return 0;
int left = maxDepth(node->left, max);
int right = maxDepth(node->right, max);
max = max(max, left + right);
return max(left, right) + 1;
}
};
java
class Solution {
//设置一个类变量,用于记录最大直径
private int max = 0;
public int diameterOfBinaryTree(TreeNode root) {
maxDepth(root);
return max;
}
private int maxDepth(TreeNode root){
if(root == null){
return 0;
}
int leftDepth = maxDepth(root.left);
int rightDepth = maxDepth(root.right);
//max记录当前的最大直径
max = Math.max(leftDepth + rightDepth, max);
//由于我计算的直径是左树高度+右树高度,所以这里返回当前树的高度,以供使用
return Math.max(leftDepth, rightDepth) + 1;
}
}
python
class Solution:
def __init__(self):
self.max = 0
def diameterOfBinaryTree(self, root: TreeNode) -> int:
self.maxDepth(root)
return self.max
def maxDepth(self, root):
if not root:
return 0
l = self.maxDepth(root.left)
r = self.maxDepth(root.right)
'''每个结点都要去判断左子树+右子树的高度是否大于self.max,更新最大值'''
self.max = max(self.max, l+r)
# 返回的是高度
return max(l, r) + 1
递归优化
c++
class Solution {
public:
int diameterOfBinaryTree(TreeNode* root) {
int max = 0;
maxDepth(root, max);
return max;
}
int maxDepth(TreeNode* node, int& max) {
if (!node) return 0;
if (m.count(node)) return m[node];
int left = maxDepth(node->left, max);
int right = maxDepth(node->right, max);
max = max(max, left + right);
return m[node] = (max(left, right) + 1);
}
private:
unordered_map<TreeNode*, int> m;
};