LeetCode543 二叉树的直径

68 阅读2分钟

leetcode.cn/problems/di…

image.png

解法一:暴力法

根据题意,二叉树的直径,其实就是左右子树的最大深度之和,那么直接的想法是对每个节点计算左右子树的最大高度,得出每个节点的直径,从而得出最大的那个直径。

求最大深度的算法我们在这个题目中实现了:juejin.cn/post/747896…

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func diameterOfBinaryTree(root *TreeNode) int {
    if root == nil{
        return 0
    }
    var res int
    traverse(root, &res)
    return res
}

func traverse(root *TreeNode, maxDiameter *int) {
    if root == nil {
        return
    }
    // 求左右子树的最大深度
    leftMax := maxDepth(root.Left)
    rightMax := maxDepth(root.Right)
    // 求每个节点的直径,并更新最大直径
    curDiameter := leftMax+rightMax
    *maxDiameter = max(*maxDiameter, curDiameter)
    // 递归求左右子节点的直径
    traverse(root.Left, maxDiameter)
    traverse(root.Right, maxDiameter)
}

func maxDepth(root *TreeNode) int{
    if root == nil{
        return 0
    }
    maxLeft := maxDepth(root.Left)
    maxRight := maxDepth(root.Right)
    return max(maxLeft, maxRight) + 1
}

func max(a, b int) int{
    if a > b {
        return a
    }
    return b
}

这个解法是正确的,但是运行时间很长,原因也很明显,traverse 遍历每个节点的时候还会调用递归函数 maxDepth,而 maxDepth 是要遍历子树的所有节点的,所以最坏时间复杂度是 O(N^2)。

这是因为前序位置无法获取子树信息,所以只能让每个节点调用 maxDepth 函数去算子树的深度

image.png

那如何优化?我们应该把计算「直径」的逻辑放在后序位置,准确说应该是放在 maxDepth 的后序位置,因为 maxDepth 的后序位置是知道左右子树的最大深度的。

解法二:优化后的后序遍历

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func diameterOfBinaryTree(root *TreeNode) int {
    if root == nil{
        return 0
    }
    var res int
    _  = maxDepth(root, &res)
    return res
}

func maxDepth(root *TreeNode, maxDiameter *int) int{
    if root == nil{
        return 0
    }
    maxLeft := maxDepth(root.Left, maxDiameter)
    maxRight := maxDepth(root.Right, maxDiameter)
    // 后续位置,已知节点左右子树最大深度,顺便更新最大直径
    curDiameter := maxLeft+maxRight
    *maxDiameter = max(*maxDiameter, curDiameter)
    return max(maxLeft, maxRight) + 1
}

func max(a, b int) int{
    if a > b {
        return a
    }
    return b
}

参考

labuladong.online/algo/essent…