Binary Tree Maximum Path Sum

迷南。 2021-12-17 10:35 314阅读 0赞

Given a binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path does not need to go through the root.

For example:
Given the below binary tree,

  1. 1
  2. / \
  3. 2 3

Return 6.

这是一道二叉树递归的终极版本,需要求二叉树中从任意结点到任意结点的最长路径。与Path Sum II(从root到leaf的路径)相比,这道题更tricky。

使用分治思路devide and conquer来解这道题,求以某个结点(node)为根的any to any最大路径,可以分解为: 1.经过该结点的路径中的最大值(如2—>1—>3)(注意如果node.left,node.right的root2any都为负就只取node.val);2.该结点左子树中any to any的最大路径, 如举例中的2;3该结点右子树中any to any 的最大路径,如举例中的3。

但是每次第1种路径需要用到以结点左孩子(node.left)为结尾的最大路径(可以翻转过来依然以node.left为起点朝下走的路径)和以结点右孩子(node.right)为起点朝下走的最大路径和。一个简单的思路是每个子问题都返回以node为起点的 root to any的和 node为根的树中的 any to any。前者是为了辅助计算,后者是为了得到最终的结果。这种代码的最终实现Java版为:

  1. public class Solution {
  2. /**
  3. * @param root: The root of binary tree.
  4. * @return: An integer.
  5. */
  6. private class ResultType {
  7. int root2Any, any2Any;
  8. ResultType(int root2Any, int any2Any) {
  9. this.root2Any = root2Any;
  10. this.any2Any = any2Any;
  11. }
  12. }
  13. private ResultType helper(TreeNode root) {
  14. if (root == null) {
  15. return new ResultType(Integer.MIN_VALUE, Integer.MIN_VALUE); //两种路径中都最少包括一个结点
  16. }
  17. // Divide
  18. ResultType left = helper(root.left);
  19. ResultType right = helper(root.right);
  20. // Conquer
  21. int root2Any =
  22. Math.max(0, Math.max(left.root2Any, right.root2Any)) + root.val;
  23. int any2Any = Math.max(left.any2Any, right.any2Any);
  24. any2Any = Math.max(maxPath,
  25. Math.max(left.root2Any, 0) +
  26. Math.max(right.root2Any, 0) + root.val);
  27. return new ResultType(root2Any,any2Any );
  28. }
  29. public int maxPathSum(TreeNode root) {
  30. ResultType result = helper(root);
  31. return result.any2Any;
  32. }
  33. }

但是思考下上面的代码就可以发现,其实并不需要保存每个结点的any2any.可以维护一个当前的最大值,一旦某个node的any2any比目前的any2any大,就更新它,最后返回这个值就可以。也就是helper函数每次只需要返回以输入的结点为根的root2any就可以了,具体代码如下:

对于树的跟节点,需要考虑两种情况,它的产生最大和的路径包含两种可能:1:包含该节点的路径: a.横跨左子树,根节点和右子树。b.左子树的一段,以根节点为结尾。c.右子树的一段,以根节点为结尾。2.左子树或右子树中的一段路径,不包含该节点。 要完成这两点,需要子节点返回:1.以子节点为终点的最大路径和。2.子节点为根的子树中的最大值。考虑到该题需要返回的是全局的最大路径和,可以直接将子树中的最大路径和更新到系统里。

  1. class Solution(object):
  2. def maxPathSum(self, root):
  3. """
  4. :type root: TreeNode
  5. :rtype: int
  6. """
  7. res = [-sys.maxint-1]
  8. self.helper(root,res)
  9. return res[0]
  10. def helper(self,node,res):
  11. if not node: #don't need to include a node
  12. return 0
  13. left = self.helper(node.left,res) #the max path sum from left node(must include left node)
  14. right = self.helper(node.right,res) #the max path sum from right node(must include right node)
  15. nodepath = max(max(left,right,0)+node.val #the max path sum from node(must include the node)
  16. maxpath = max(left,0)+max(right,0)+node.val #the max path that cross the node (but not start from, any to any)
  17. res[0] = max(res[0],maxpath)
  18. return nodepath

转载于:https://www.cnblogs.com/sherylwang/p/5499595.html

发表评论

表情:
评论列表 (有 0 条评论,314人围观)

还没有评论,来说两句吧...

相关阅读