(沒作出來,典型題目重要)算法
二叉樹中的最大路徑和(hard)函數
給定一個非空二叉樹,返回其最大路徑和。url
本題中,路徑被定義爲一條從樹中任意節點出發,達到任意節點的序列。該路徑至少包含一個節點,且不必定通過根節點。spa
示例 1:.net
輸入: [1,2,3] 1 / \ 2 3 輸出: 6
示例 2:code
輸入: [-10,9,20,null,null,15,7] -10 / \ 9 20 / \ 15 7 輸出: 42
關鍵點:
1.和求根節點到葉節點的最長路徑的題目同樣(最長路徑爲左子樹或右子樹最大值),遞歸的求左子樹好右子樹的長度。用全局變量記錄該題的最長路徑(左子樹返回值(若是大於0的話),加上右子樹的返回值(若是大於0的話),再加上本身的值)
2.由於沒必要達到葉節點,左或右子樹的最長路徑爲Math.max(0, getMaxPathSum(root.left)),必定大於0
連接:https://www.nowcoder.com/questionTerminal/da785ea0f64b442488c125b441a4ba4a
來源:牛客網
/* * 124. Binary Tree Maximum Path Sum * 解題思路:(轉載自:<a href="http://blog.csdn.net/linhuanmars/article/details/22969069" target="_blank">http://blog.csdn.net/linhuanmars/article/details/22969069) * 這道題是求樹的路徑和的題目,不過和日常不一樣的是這裏的路徑不只能夠從根到某一個結點, * 並且路徑能夠從左子樹某一個結點,而後到達右子樹的結點,就像題目中所說的能夠起始和終結於任何結點。 * 在這裏樹沒有被當作有向圖,而是被當成無向圖來尋找路徑。 * 由於這個路徑的靈活性,咱們須要對遞歸返回值進行一些調整,而不是一般的返回要求的結果。 * 在這裏,函數的返回值定義爲以本身爲根的一條從根到子結點的最長路徑(這裏路徑就不是當成無向圖了, * 必須往單方向走)。 * 這個返回值是爲了提供給它的父結點計算自身的最長路徑用, * 而結點自身的最長路徑(也就是能夠從左到右那種)則只需計算而後更新便可。 * 這樣一來,一個結點自身的最長路徑就是它的左子樹返回值(若是大於0的話), * 加上右子樹的返回值(若是大於0的話),再加上本身的值。 * 而返回值則是本身的值加上左子樹返回值, * 右子樹返回值或者0(注意這裏是「或者」,而不是「加上」,由於返回值只取一支的路徑和)。 * 在過程當中求得當前最長路徑時比較一下是否是目前最長的,若是是則更新。 * 算法的本質仍是一次樹的遍歷,因此複雜度是O(n)。而空間上仍然是棧大小O(logn)。 */ // 由於maxPathSum不必定通過根節點,因此用maxValue整個遍歷過程當中出現過的最大值 int maxValue = 0; public int maxPathSum(TreeNode root) { if (root == null) return 0; maxValue = Integer.MIN_VALUE; getMaxPathSum(root); return maxValue; } private int getMaxPathSum(TreeNode root) { if (root == null) return 0; //由於節點的值能夠爲負數,因此最大值取0和子樹值的較大者 int leftMax = Math.max(0, getMaxPathSum(root.left)); int rightMax = Math.max(0, getMaxPathSum(root.right)); //若是將當前root做爲根節點,那麼最大值是root.val+左子樹最大值+右子樹最大值 maxValue = Math.max(maxValue, root.val + leftMax + rightMax); //只能返回左右子樹中較大值加上root.val return Math.max(0, root.val + Math.max(leftMax, rightMax)); }</a>