求二叉树上任意两个节点之间的最大和,应该怎么优化?

2019-02-20 15:19:31 +08:00
 Elethom

刚才面试的时候遇到的题。思路大概是用 maxTree() 算从 root 开始的最大值,用 maxNodes() 算任意两节点之间的最大值,每个 node 比较 maxNodes(left)maxNodes(right)maxTree(left) + maxTree(right) + value 三者之间的最大值,用递归。

但是感觉每个 node 都要算好几遍,而且还是递归,效率会很低,遇到大一点的要炸。有什么办法可以优化吗?

代码:

class TreeNode {
    var value: Int
    var left: TreeNode?
    var right: TreeNode?
    init(_ value: Int) {
        self.value = value
    }
}

func maxTree(_ root: TreeNode) -> Int { // max from root
    if root.left == nil && root.right == nil {
        return root.value
    } else if root.left == nil {
        return maxTree(root.right!) + root.value
    } else if right == nil {
        return maxTree(root.left!) + root.value
    }
    return max(maxTree(root.left!), maxTree(root.right!)) + root.value
}

func maxNodes(_ root: TreeNode) -> Int { // max between any 2 nodes
    if root.left == nil && root.right == nil {
        return root.value
    } else if root.left == nil {
        return max(maxNodes(root.right!), root.value + maxTree(root.right!))
    } else if root.right == nil {
        return max(maxNodes(root.left!), root.value + maxTree(root.left!))
    }
    return max(max(maxNodes(root.left!), maxNodes(root.right!)), maxTree(root.left!) + maxTree(root.right!) + root.value)
}
2757 次点击
所在节点    算法
6 条回复
sigmapi
2019-02-20 16:24:08 +08:00
用 max, max2 分别记录最大值和次大值,遍历树,更新 max 和 max2
最后返回 max + max2
aijam
2019-02-20 16:30:39 +08:00
其实就是找出最大的两个数相加,和 array 里找最大两个数的差别就是遍历方式不同而已。
rayingecho
2019-02-20 16:41:04 +08:00
rayingecho
2019-02-20 16:43:54 +08:00
楼主你的算法思路是没问题的, 但是有很多的重复计算, 加上一个 cache 缓存已经计算过的值就可以了
当然也可以像我在 #3 贴的那样换成 bottom-up dp, 不需要额外空间
Elethom
2019-02-20 16:50:58 +08:00
谢谢各位。

@rayingecho
发现了,把重复的计算去掉就好了。不用 cache,计算的时候直接比较就行。
MinakoKojima
2019-04-18 10:25:26 +08:00
这个问题是一般树的直径问题的一个特例。从任一点向下 dfs() or bfs() 到距离最远的点 u,再从 u 出发找距离最远的点 v,u 与 v 之间的距离就是直径,这种算法没有递归常数更小。

[证明]( https://blog.csdn.net/su20145104009/article/details/51297098)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/536905

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX