[LeetCode]Binary Tree Maximum Path Sum

Binary Tree Maximum Path Sum

Given a binary tree, find the maximum path sum.node

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,this

1
     / \
    2   3

Return 6.spa

分析

這道題開始咱們要明白符合題目要求的路徑有什麼特色,要求是樹種任意兩個點便可,不必定要通過樹的root, 路徑的順序必須是正常父子順序。因此會發現,對任意一條路徑,必然會有本身的root, 因此咱們只要找出以每一個node爲root的路徑的最大值,而後維護一個全局最大值,找的過程當中不斷更新全局最大值便可。code

接下來就要考慮對一個node而言怎麼找出以其爲root的路徑最大值,方法很簡單,找出以左邊node向下的最大值加上以右邊node向下的最大值再加上自己值便可,注意若是左右邊值或爲負數,會影響本身路徑的最大值,放棄加。找到以本身爲root的路徑最大值後,與全局最大值比較便可。同時,也應該返回以本身爲開頭,向下的路徑最大值,方法就是把取左右向下較大值加上本身自己值便可。io

這道題也能夠有個Follow up, 好比最大值路徑的node不是父子關係,要求最大值路徑上的node不能夠相鄰(Google面試題)function

具體分析見下文class

複雜度

time: O(n), space: O(h)方法

代碼

public class Solution {
    public int maxPathSum(TreeNode root) {
        int[] max = {Integer.MIN_VALUE}; // 全局最大值
        helper(root, max);
        return max[0];
    }
    
    public int helper(TreeNode node, int[] max) {
        if (node == null)
            return 0;
        
        // 分別返回以左右子node爲起始點的路徑的最大值
        int left = helper(node.left, max);
        int right = helper(node.right, max);
                    
        // 加上本身自己值後,計算返回值及更新全局最大值                      
        int leftMax = Math.max(0, left);
        int rightMax = Math.max(0, right);
        max[0] = Math.max(max[0], node.val + leftMax + rightMax);
        return node.val + Math.max(leftMax, rightMax);
    }
}

Follow up

要求路徑上的點不能夠是父子關係,即不能夠相鏈接。im

好比:

1
     / \
    2   3
   / \
  1   8

Return 11(8 + 3).

分析

方法其實與上一題是同樣的,只不過咱們須要考慮多一點狀況,對於某一個node而言,會有兩種狀況來算以該點爲root的路徑最大值,一是最大值包含該點,二是最大值不包含該點。一樣對於helper function返回值而言也是,不盡須要返回包含該點的最大值,也須要返回不包含該點向下的最大值,由於這兩個值父節點都會須要用。因此咱們須要把helper function改爲返回兩個值。

複雜度

time: O(n), space: O(1)

代碼

public class Solution {
    public int maxPathSum(TreeNode root) {
        int[] max = {Integer.MIN_VALUE};
        helper(root, max);
        return max[0];
    }


    public int[] helper(TreeNode node, int[] max) {
        // res[0]表示包含該點的向下路徑最大值,res[1]表示不包含該點向下路徑最大值
        int[] res = new int[2];

        if (node == null)
            return res;

        int[] left = helper(node.left, max);
        int[] right = helper(node.right, max);

        int leftMax = 0;
        int rightMax = 0;

        // 包含自己node, 因爲最大值路徑node不能鏈接,不可以使用left[0]及right[0]
        leftMax = Math.max(leftMax, left[1]);
        rightMax = Math.max(rightMax, right[1]);
        max[0] = Math.max(max[0], node.val + leftMax + rightMax);
        res[0] = node.val + Math.max(leftMax, rightMax);

        // 不包含自己node, 左右向下路徑不管包不包含左右子節點均可以須要考慮
        leftMax = 0;
        rightMax = 0;
        leftMax = Math.max(leftMax, Math.max(left[0], left[1]));
        rightMax = Math.max(rightMax, Math.max(right[0], right[1]));
        max[0] = Math.max(max[0], leftMax + rightMax);
        res[1] = Math.max(leftMax, rightMax);

        return res;
    }
}
相關文章
相關標籤/搜索