[Leetcode] Binary Tree Maximum Path Sum
這是LeetCode上的一道題目,需要求二叉樹中兩點路徑的最大和。原題是
https://oj.leetcode.com/problems/binary-tree-maximum-path-sum/
Given a binary tree, find the maximum path sum.
The path may start and end at any node in the tree.
For example: Given the below binary tree,
1/ \2 3Return 6.
?
大概的想法其實很簡單,類似于用分治法求數組連續和的最大值。最大值有三種可能,第一種是起點和終點最大和在左子樹中,第二種是起點和終點最大和在右子樹中,第三種是起點在左子樹中,終點在右子樹中。第三種要求路徑必須通過根節點,因此其左右子樹中的路徑只能是從左右子樹的根節點到其中的某個節點。根據這個思路,就可以寫出如下的代碼。
class Solution { public:int maxPathSum(TreeNode *root) {if(root==NULL)return 0;else{if(root->left==NULL && root->right==NULL)return root->val;int maxLeft = maxPathSum(root->left);int maxRight = maxPathSum(root->right);int maxLeafLeft = max(0, maxLeafSum(root->left));int maxLeafRight = max(0, maxLeafSum(root->right));int sumWithRoot = root->val + maxLeafLeft + maxLeafRight;return max(maxLeft, maxRight, sumWithRoot);} }int maxLeafSum(TreeNode* root){if(root==NULL)return 0;else{if(root->left==NULL && root->right==NULL)return root->val;else{return root->val + max(maxLeafSum(root->left), maxLeafSum(root->right)); } } } }
這個方法雖然結果是正確的,但是很不幸嚴重超時。雖然我知道瓶頸是出在maxLeafSum()上,這其中有很多的冗余計算,但是沒有想到該如何優化。后來看了別人的解答,才發現自己對遞歸的理解還是不夠深入。我參考了soulmachine的解答(順便說一下,這個解答是我看過的最詳細的解答了 https://github.com/soulmachine/leetcode?),他用的代碼是
這里的DFS就是返回從根節點到某個子節點的路徑最大和。咋看一下似乎不對,怎么只考慮了路徑通過根節點的情形呢,即開頭我們討論的第三種情形?這個地方的巧妙之處在于,我們所要求的最大和路徑必定是滿足其起點和終點在某個節點的兩側。所以只要我們用某個把這個函數應用到所有節點之上,把每次的計算結果與一個全局變量比較,就可以得到正確的結果。
非常巧妙的方法!這也說明遞歸有時候可以簡化問題,甚至想得越簡單越好,只要我們保證最優解肯定對于某個節點滿足我們給定的形式。
?
用類似的辦法可以計算二叉樹所有節點中的最大值、最小值。
?
轉載于:https://www.cnblogs.com/darkphoton/p/4141417.html
總結
以上是生活随笔為你收集整理的[Leetcode] Binary Tree Maximum Path Sum的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IOS 控件 - Swift 集成 IO
- 下一篇: careercup-树与图 4.6