[LeetCode] 124. Binary Tree Maximum Path Sum
A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence at most once. Note that the path does not need to pass through the root.
The path sum of a path is the sum of the node's values in the path.
Given the root
of a binary tree, return the maximum path sum of any non-empty path.
Example 1:
Input: root = [1,2,3] Output: 6 Explanation: The optimal path is 2 -> 1 -> 3 with a path sum of 2 + 1 + 3 = 6.
Example 2:
Input: root = [-10,9,20,null,null,15,7] Output: 42 Explanation: The optimal path is 15 -> 20 -> 7 with a path sum of 15 + 20 + 7 = 42.
Constraints:
- The number of nodes in the tree is in the range
[1, 3 * 104]
. -1000 <= Node.val <= 1000
二叉树的最大路径和。
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。该路径 至少包含一个 节点,且不一定经过根节点。
路径和 是路径中各节点值的总和。
给你一个二叉树的根节点 root ,返回其 最大路径和 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
注意第二个例子,节点值是会存在负数的。思路是后序遍历,因为路径和总是要包括左孩子val + 右孩子val + 当前节点val(注意不是根节点)。做法跟其他后序遍历的题几乎都一样,也是创建一个全局变量记录最后的结果。注意因为路径和有可能是负的所以创建的全局变量的初始值是 Integer.MIN_VALUE。helper 函数里面去递归左子树和右子树的时候,记得是跟 0 比较谁大,因为节点值包括负数,加上小于 0 的节点只会拖垮最后的结果。全局变量 res 算的是 root.val + left + right,也就是把所有节点都当做一个根节点为子树,能得到的最大的路径和;但是因为这里我们做的是后序遍历,所以对于每一个节点node来说, helper 函数往 node 的父节点返回的应该是左子树和右子树较大的一枝 + 当前节点值 node.val。
比如第二个例子,对于节点 20 来说,他的左孩子能贡献的值是 15,右孩子能贡献 7,以他自己为根节点的子树就能获得 20 + 15 + 7 = 42。但是如果 20 再往自己的父节点贡献值的时候,他就只能左右孩子二选一了,因为题目要求是路径上的点只能出现一次(引用)。
很多后序遍历的题,最后求的结果跟helper函数往父节点返回的值都是有差别的,这个需要多练习。
时间O(n)
空间O(n)
Java实现
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 class Solution { 11 int res; 12 13 public int maxPathSum(TreeNode root) { 14 // corner case 15 if (root == null) { 16 return 0; 17 } 18 res = Integer.MIN_VALUE; 19 helper(root); 20 return res; 21 } 22 23 public int helper(TreeNode root) { 24 if (root == null) { 25 return 0; 26 } 27 // 注意左右孩子的贡献值是可选的所以如果小于0就不选即可 28 // 这样经过当前node的贡献值就仅仅是root.val 29 int left = Math.max(0, helper(root.left)); 30 int right = Math.max(0, helper(root.right)); 31 res = Math.max(res, left + right + root.val); 32 return Math.max(left, right) + root.val; 33 } 34 }
JavaScript实现
1 /** 2 * @param {TreeNode} root 3 * @return {number} 4 */ 5 var maxPathSum = function (root) { 6 let res = -Infinity; 7 let helper = function (root) { 8 if (root == null) return 0; 9 let left = Math.max(0, helper(root.left)); 10 let right = Math.max(0, helper(root.right)); 11 // let newPath = root.val + left + right; 12 res = Math.max(root.val + left + right, res); 13 return Math.max(left, right) + root.val; 14 } 15 helper(root); 16 return res; 17 };