LeetCode——543.二叉树的直径

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。

示例 :
给定二叉树

      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;
};
原文地址:https://www.cnblogs.com/wwj99/p/12453982.html