victory的博客

长安一片月,万户捣衣声

0%

leetcode | 543.二叉树的直径

543.二叉树的直径

题目描述

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

示例 :
给定二叉树

      1
     / \
    2   3
   / \     
  4   5    

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

题目链接

思路

  1. 深度优先搜索
    首先我们知道一条路径的长度为该路径经过的节点数减一,所以求直径(即求路径长度的最大值)等效于求路径经过节点数的最大值减一
    而任意一条路径均可以被看作由某个节点为起点,从其左儿子和右儿子向下遍历的路径拼接得到。

假设我们知道对于该节点的左儿子向下遍历经过最多的节点数 LLL (即以左儿子为根的子树的深度) 和其右儿子向下遍历经过最多的节点数 RRR (即以右儿子为根的子树的深度),那么以该节点为起点的路径经过节点数的最大值即为 L+R+1L+R+1L+R+1 。
我们记节点 node 为起点的路径经过节点数的最大值为 dnode​ ,那么二叉树的直径就是所有节点 dnode​的最大值减一。

算法流程为:我们定义一个递归函数 depth(node) 计算 dnode​,函数返回该节点为根的子树的深度。先递归调用左儿子和右儿子求得它们为根的子树的深度 L 和 R ,则该节点为根的子树的深度即为
max(L,R)+1,该节点的 dnode​值为 L+R+1,递归搜索每个节点并设一个全局变量 ans 记录 dnode​的最大值,最后返回 ans-1 即为树的直径。

代码

class TreeNode(object):  # Definition for a binary tree node.
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution(object):
    def diameterOfBinaryTree(self, root):
        """
        这种解法路径必须经过根节点,由题目可知路径可能穿过
        也可能不穿过根节点,故此解法不符合题意
        :type root: TreeNode
        :rtype: int
        """
        left = self.get_depth(root.left)
        right = self.get_depth(root.right)
        return left + right
    
    def get_depth(self, root):
        if not root:
            return 0
        left_depth = self.get_depth(root.left)
        right_depth = self.get_depth(root.right)
        return max(left_depth, right_depth) + 1
    
    def diameterOfBinaryTree1(self, root):
        self.ans = 1
        def depth(node):
            if not node:
                return 0
            L = depth(node.left)
            R = depth(node.right)
            self.ans = max(self.ans, L + R + 1)
            return max(L, R) + 1
        depth(root)
        return self.ans - 1  # 一条路径的长度为该路径经过的节点数减一

if __name__ == "__main__":
    slt = Solution()
    root = TreeNode(1)
    node2 = TreeNode(2)
    node3 = TreeNode(3)
    node4 = TreeNode(4)
    node5 = TreeNode(5)
    root.left = node2
    root.right = node3
    node2.left = node4
    node2.right = node5
    # diameter = slt.diameterOfBinaryTree(root)
    diameter = slt.diameterOfBinaryTree1(root)
    print("diameter:", diameter)