二叉樹最大路徑和問題
二叉樹最大路徑和問題
作者:Grey
原文地址:
題目描述
路徑 被定義為一條從樹中任意節點出發,沿父節點-子節點連線,達到任意節點的序列。同一個節點在一條路徑序列中 至多出現一次 。該路徑 至少包含一個 節點,且不一定經過根節點。
路徑和 是路徑中各節點值的總和。
給你一個二叉樹的根節點 root ,返回其 最大路徑和 。
題目連結見: LeetCode 124. Binary Tree Maximum Path Sum
主要思路
本題使用二叉樹遞迴套路方法,相關技巧見使用二叉樹的遞迴套路來解決的問題
定義如下資料結構
public static class Info { // 最大路徑和 public int maxPathSum; // 頭結點一直往一側扎,能扎到的最大值是多少 public int maxPathSumFromHead; public Info(int path, int head) { maxPathSum = path; maxPathSumFromHead = head; } }
接下來定義遞迴函式
Info process(TreeNode head)
遞迴含義表示:head 為頭的二叉樹,得到的 Info 資訊是什麼。
主函式只需要呼叫
public static int maxPathSum(TreeNode root) {
if (root == null) {
return 0;
}
return process(root).maxPathSum;
}
即為要求的結果。
接下來就是process
方法的實現,有如下幾種情況
base case ,如果head == null
,直接返回new Info(Integer.MIN_VALUE,Integer.MIN_VALUE)
接下來找左右子樹的資訊
Info leftInfo = process(head.left);
Info rightInfo = process(head.right);
整合成以 head 為頭的樹的資訊,
其中以 head 為頭的樹的maxPathSumFromHead
變數有如下幾種情況
-
只包含
head.val
,這種情況暗示左右子樹彙報的maxPathSumFromHead
均為負數; -
包含
head.val
和左子樹的maxPathSumFromHead
,這種情況暗示右子樹的maxPathSumFromHead
小於0,且左子樹的maxPathSumFromHead
以上兩種情況都可以歸結為
int maxPathSumFromHead =
head.val + Math.max(Math.max(leftInfo.maxPathSumFromHead, rightInfo.maxPathSumFromHead), 0);
以 head 為頭的樹的maxPathSum
包含如下幾種情況
-
只包含
leftInfo.maxPathSum
; -
只包含
rightInfo.maxPathSum
; -
只包含
head.val + Math.max(0, leftInfo.maxPathSumFromHead) + Math.max(0, rightInfo.maxPathSumFromHead))
上述三種情況可以統一寫成
int maxPathSum =
Math.max(
Math.max(leftInfo.maxPathSum, rightInfo.maxPathSum),
head.val
+ Math.max(0, leftInfo.maxPathSumFromHead)
+ Math.max(0, rightInfo.maxPathSumFromHead));
完整程式碼見
class Solution {
public static int maxPathSum(TreeNode root) {
if (root == null) {
return 0;
}
return process(root).maxPathSum;
}
// 任何一棵樹,必須彙報上來的資訊
public static class Info {
public int maxPathSum;
public int maxPathSumFromHead;
public Info(int path, int head) {
maxPathSum = path;
maxPathSumFromHead = head;
}
}
public static Info process(TreeNode head) {
if (null == head) {
return new Info(Integer.MIN_VALUE, Integer.MIN_VALUE);
}
Info leftInfo = process(head.left);
Info rightInfo = process(head.right);
int maxPathSumFromHead =
head.val + Math.max(Math.max(leftInfo.maxPathSumFromHead, rightInfo.maxPathSumFromHead), 0);
int maxPathSum =
Math.max(
Math.max(leftInfo.maxPathSum, rightInfo.maxPathSum),
head.val
+ Math.max(0, leftInfo.maxPathSumFromHead)
+ Math.max(0, rightInfo.maxPathSumFromHead));
return new Info(maxPathSum, maxPathSumFromHead);
}
}