387,二叉樹中的最大路徑和

資料結構和演算法 發表於 2020-09-23

想了解更多資料結構以及演算法題,可以關注微信公眾號“資料結構和演算法”,每天一題為你精彩解答。也可以掃描下面的二維碼關注
在這裡插入圖片描述

給定一個非空二叉樹,返回其最大路徑和。

路徑被定義為一條從樹中任意節點出發,達到任意節點的序列。該路徑至少包含一個節點,且不一定經過根節點。


示例 1:
在這裡插入圖片描述

示例 2:

在這裡插入圖片描述

問題分析

這道題要求的最大路徑和如果是從根節點開始到葉子節點就好辦了,我們可以通過遞迴的方式,從下往上,捨去比較小的路徑節點,保留比較大的節點。


但這道題要求的最大路徑和並不一定經過根節點,如果再使用上面的方式就行不通了,對於這道題我們可以分為4種情況來討論


1,只要當前節點,捨棄子節點。比如下面結點2的左右子節點都是負數,如果是負數我們還不如不要,所以直接捨棄子節點。

在這裡插入圖片描述

2,保留當前節點和左子節點。比如下面結點2的右子節點是負數,我們直接捨棄右子節點,但左子節點不是負數,我們可以保留左子節點。

在這裡插入圖片描述

3,保留當前節點和右子節點。比如下面結點2的左子節點是負數,我們直接捨棄左子節點,但右子節點不是負數,我們可以保留右子節點。

在這裡插入圖片描述

4,保留當前節點和兩個子節點。比如下面結點2的左右子節點都不是負數,我們都可以留下。

在這裡插入圖片描述

上面的1,2,3都可以作為子樹的一部分再繼續計算,我們可以使用同一個公式,取左右子節點最大的那個即可,如果都小於0我們不要了,下面公式中left是左子樹的值,right是右子樹的值

在這裡插入圖片描述

而4是不能在作為子樹的一部分參與計算的,因為已經分叉了,比如下面的3→2→4是不能再和結點1進行組合的。第4種情況如果左右子樹有一個是小於0的我們還不如不選,如果都大於0我們都要選的。

在這裡插入圖片描述

在這裡插入圖片描述

搞懂了上面的分析過程,程式碼就很容易寫出來了,我們最後來看下程式碼

程式碼部分

private int maxValue = Integer.MIN_VALUE;

public int maxPathSum(TreeNode root) {
    maxPathSumHelper(root);
    return maxValue;
}

public int maxPathSumHelper(TreeNode root) {
    if (root == null)
        return 0;
    //左子節點的值
    int left = maxPathSumHelper(root.left);
    //右子節點的值
    int right = maxPathSumHelper(root.right);
    //第4種情況
    int cur = root.val + Math.max(0, left) + Math.max(0, right);
    //第1,2,3三種情況,返回當前值加上左右子節點的最大值即可,如果左右子節點都
    //小於0,還不如不選
    int res = root.val + Math.max(0, Math.max(left, right));
    //記錄最大value值
    maxValue = Math.max(maxValue, Math.max(cur, res));
    //第1,2,3種情況還可以再計算,所以返回的是res
    return res;
}

在這裡插入圖片描述