[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 };

 

LeetCode 题目总结

posted @ 2020-03-18 14:34  CNoodle  阅读(424)  评论(0编辑  收藏  举报