Leetcode daily 20/03/10 二叉树的直径

二叉树的直径

-题目-

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

-示例-

给定二叉树

      1
     / \
    2   3
   / \
  4   5

返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。
注意:两结点之间的路径长度是以它们之间边的数目表示。


-方法1-

  对于一棵子树\(t_i\),其直径di为任意两个节点路径长度最大值,也就是:(左子树 \(t_{left}\) 到某叶节点的距离最大值 + 1) + (右子树 \(t_{right}\) 到某叶节点的距离最大值 + 1)。如果左子树或右子树为空,则此子树\(t_i\)的直径di为:(非空子树 \(t_{notNone}\) 到某叶节点的距离最大值 + 1)。若左右子树皆空,则该子树\(t_i\)的直径di为0。
  整棵树的直径就是每棵子树的直径的最大值max(\(d_i\))。

  算法:

  • 设置全局变量rst
  • 遍历树:
    • 对每一棵子树求直径 di
    • dirst较大值为rst
  • 最后得到的rst为整棵树的直径。

-ac代码-

class Solution:
    def __init__(self):
        self.rst = 0

    def maxD(self, root):
        maxLD = self.maxD(root.left) + 1 if root.left else 0
        maxRD = self.maxD(root.right) + 1 if root.right else 0
        di = maxLD + maxRD

        self.rst = max(self.rst, di)

        return max(maxLD, maxRD)

    def diameterOfBinaryTree(self, root: TreeNode) -> int:
        if not root:
            return 0

        self.maxD(root)

        return self.rst

-复杂度-

  • \(T(n) = O(n)\) (遍历每个节点求直径\(d_i\)
  • \(S(n) = O(depth)\) (递归需要栈,栈长度为树深度)

-方法2-

  子树\(t_i\)的直径di也可以是:左子树深度depthL + 右子树深度depthR。若子树为空,则深度为0,否则为(左子树深度depthL和右子树深度depthR较大值) + 1。

  算法:

  • 设置全局变量rst
  • 遍历树:
    • 对每一棵子树求直径 di
    • dirst较大值为rst
  • 最后得到的rst为整棵树的直径。

-ac代码-

class Solution:
    def __init__(self):
        self.rst = 0

    def depth(self, root):
        if not root:
            return 0

        depthL = self.depth(root.left)
        depthR = self.depth(root.right)
        di = depthL + depthR

        self.rst = max(self.rst, di)

        return max(depthL, depthR) + 1

    def diameterOfBinaryTree(self, root: TreeNode) -> int:
        if not root:
            return 0

        self.depth(root)

        return self.rst

-复杂度-

  • \(T(n) = O(n)\) (遍历每个节点求直径\(d_i\)
  • \(S(n) = O(depth)\) (递归需要栈,栈长度为树深度)

-笔记-

  • 题目-笔记:题目求的是两个节点之间路径(边数)最大值,可能不包含根节点。
  • 算法-笔记:
        if root.right is None:
            return self.maxD(root.left) + 1
        elif root.left is None:
            return self.maxD(root.right) + 1
        elif root.left is None and root.right is None:
            return 0

  以上代码第三个if不会被执行。

  • 算法-笔记:空节点可能需要额外操作。
posted @ 2020-03-10 16:08  Sola~  阅读(111)  评论(0编辑  收藏  举报