題目
給定一個非空二叉樹,返回其最大路徑和。
本題中,路徑被定義爲一條從樹中任意節點出發,達到任意節點的序列。該路徑至少包含一個節點,且不一定經過根節點。
示例 1:
輸入: [1,2,3]
1
/ \
2 3
輸出: 6
示例 2:
輸入: [-10,9,20,null,null,15,7]
-10
/ \
9 20
/ \
15 7
輸出: 42
解題思路
先實現一個函數能夠計算二叉樹中的一個節點的最大貢獻值,具體而言,就是在以該節點爲根節點的子樹中尋找以該節點爲起點的一條路徑,使得該路徑上的節點值之和最大:
1)空節點的最大貢獻值等於 0。
2)非空節點的最大貢獻值等於該節點值加上其左、右子節點的最大貢獻值中的較大一方。
3)對於葉節點來說,最大貢獻值等於節點值。
對於二叉樹中的一個節點,該節點的最大路徑和取決於該節點的值與該節點的左右子節點的最大貢獻值,
1)如果子節點的最大貢獻值大於等於 0,則計入該節點的最大路徑和,
2)如果子節點的最大貢獻值小於 0,則不計入該節點的最大路徑和(可以將其簡單設置爲0,方便計算)。
3)維護一個全局變量 res 存儲最大路徑和,在遞歸過程中更新 res 的值,最後得到的 res 的值即爲二叉樹中的最大路徑和。
複雜度分析:
時間複雜度:O(N),其中 N 是二叉樹中的節點個數。對每個節點訪問不超過 2 次。
空間複雜度:O(N),其中 N 是二叉樹中的節點個數。空間複雜度主要取決於遞歸調用層數,最大層數等於二叉樹的高度,最壞情況下,二叉樹的高度等於二叉樹中的節點個數。
代碼
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
// 設定一個全局變量存儲最終結果
private int res = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
getMaxSum(root);
return res;
}
private int getMaxSum(TreeNode root){
if(root == null){
return 0;
}
// 如果子樹的最大貢獻值小於 0,就將其置 0,表示最大路徑不包含子樹
int left = Math.max(0, getMaxSum(root.left));
int right = Math.max(0, getMaxSum(root.right));
// 更新最大路徑和
res = Math.max(res, left + root.val + right);
return Math.max(left, right) + root.val;
}
}