LeetCode 124. 二叉樹中的最大路徑和 | Python
124. 二叉樹中的最大路徑和
題目來源:力扣(LeetCode)
題目
給定一個非空二叉樹,返回其最大路徑和。
本題中,路徑被定義為一條從樹中任意節點出發,達到任意節點的序列。該路徑至少包含一個節點,且不一定經過根節點。
示例 1:
輸入: [1,2,3]
1
/
2 3
輸出: 6
示例 2:
輸入: [-10,9,20,null,null,15,7]
-10
/
9 20
/
15 7
輸出: 42
解題思路
思路:遞迴
題目中所給出的路徑概念是指【一條從樹中任意節點出發,達到任意節點的序列。該路徑至少包含一個節點,且不一定經過根節點】。
也就是說,要求出路徑和,得計算節點能提供的最大貢獻值。
對於節點能提供的貢獻值,分為如下部分:
- 空節點提供的貢獻值為 0;
- 對於非空節點提供的貢獻值,等於當前節點的值與其子節點中提供最大貢獻值的和。
現在以示例 1 來分析說明下:
輸入: [1,2,3]
1
/
2 3
在這裡葉子節點 2
,3
,能提供的貢獻值就是 2, 3。
而葉子節點 1,能夠提供的貢獻值為 1+2
或 1+3
。
那我們假設:如果節點 1 前面還有父節點,那麼這裡可能的路徑就會變成:
- 2 + 1 + 3
- 2 + 1 + 1 的父節點
- 3 + 1 + 1 的父節點
其中第一種情況,就是求節點的最大路徑和。這裡節點的最大路徑和取決於該節點與其左右子節點的最大貢獻值之和。當然,在這裡,如果子節點的貢獻值為負,則選擇不納入。因為負數的貢獻值新增進來反而會讓結果變小。
對於第二種和第三種情況來說,這裡就是遞迴求得左右子節點的貢獻值,從中取更優的方案。
這裡最主要的就是維護一個儲存最大路徑和的變數 max_path_sum
,遞迴的過程中維護更新這個值,從而求得最大值。
具體的程式碼實現如下。
程式碼實現
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def __init__(self):
# 儲存最大路徑和
self.max_path_sum = float('-inf')
def maxPathSum(self, root: TreeNode) -> int:
def max_contr(node):
# 遞迴求節點最大貢獻值
# 同時維護經過節點的最大路徑和
# 空節點的貢獻值為 0
if not node:
return 0
# 遞迴計算左子節點的貢獻值,
left = max(0, max_contr(node.left))
# 遞迴計算右子節點的貢獻值
right = max(0, max_contr(node.right))
# 經過當前節點的最大路徑和
self.max_path_sum = max(self.max_path_sum, left + node.val + right)
# 當前節點的貢獻值,取左右子節點中的更優方案
node_contr = node.val + max(0, max(left, right))
# 這裡返回的貢獻值是給當前節點的上游節點
return node_contr
max_contr(root)
return self.max_path_sum
實現結果
總結
- 從題目中得到的資訊可以知道,要求最大路徑和,需要求得節點能夠提供的貢獻值。
- 對於節點而言,提供的貢獻值分為兩部分:
- 空節點的貢獻值為 0;
- 對於非空節點而言,當前節點能提供的貢獻值為當前節點的值與其子節點中能提供的最大貢獻值之和
- 對於非空節點而言,我們需要遞迴的方法求得每個節點的貢獻值。同時,需要維護最大路徑和,在這裡,該節點的路徑和取決於當前節點的值與其左右子節點的最大貢獻值。
- 這裡需要注意:當貢獻值為負時,不計入節點的最大路徑和。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2508/viewspace-2825699/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 124. 二叉樹中的最大路徑和二叉樹
- [Python手撕]二叉樹中的最大路徑和Python二叉樹
- 387,二叉樹中的最大路徑和二叉樹
- LintCode 二叉樹中的最大路徑和二叉樹
- 每日一道演算法題--leetcode 124--二叉樹中的最大路徑和--python演算法LeetCode二叉樹Python
- 【LeetCode擊敗99%+】二叉樹路徑總和LeetCode二叉樹
- 二叉樹路徑總和二叉樹
- LeetCode第 543 題:二叉樹的直徑(C++)LeetCode二叉樹C++
- 滿二叉樹、完全二叉樹、平衡二叉樹、二叉搜尋樹(二叉查詢樹)和最優二叉樹二叉樹
- leetcode 每日一題 543 二叉樹的直徑 dfs方法LeetCode每日一題二叉樹
- 二叉樹和為某種所有路徑二叉樹
- 列印二叉樹的所有路徑二叉樹
- 【LeetCode(Java) - 298】二叉樹最長連續序列LeetCodeJava二叉樹
- 二叉樹任意兩個節點間的最大距離(Java,LeetCode 543二叉樹的直徑 遞迴)二叉樹JavaLeetCode遞迴
- 霍夫曼樹(最優二叉樹)的實現二叉樹
- LeetCode題解(Offer26):判斷二叉樹A是否為二叉樹B的子樹(Python)LeetCode二叉樹Python
- 二叉樹路徑查詢二叉樹
- Leetcode——94.二叉樹的中序遍歷LeetCode二叉樹
- 【LeetCode-二叉樹】二叉樹前序遍歷LeetCode二叉樹
- 二叉樹最大距離(直徑)二叉樹
- 【模板題】 543. 二叉樹的直徑二叉樹
- 5分鐘瞭解二叉樹之LeetCode裡的二叉樹二叉樹LeetCode
- Python演算法和資料結構:在二叉樹中找到和為sum的所有路徑Python演算法資料結構二叉樹
- 資料結構中的樹(二叉樹、二叉搜尋樹、AVL樹)資料結構二叉樹
- LeetCode 對稱二叉樹LeetCode二叉樹
- LeetCode——671. 二叉樹中第二小的節點LeetCode二叉樹
- 根據二叉樹的前序遍歷和中序遍歷輸出二叉樹;二叉樹
- 二叉樹的插入和搜尋–python實現二叉樹Python
- 平衡樹和二叉樹的區別二叉樹
- 二叉搜尋樹和二叉樹的最近公共祖先二叉樹
- 樹(1)--樹和二叉樹的基本定義二叉樹
- 樹和二叉樹簡介二叉樹
- Leetcode 700. 二叉搜尋樹中的搜尋(DAY 2)LeetCode
- 程式碼隨想錄演算法訓練營第十七天|leetcode654. 最大二叉樹、leetcode617.合併二叉樹、leetcode700.二叉搜尋樹中的搜尋、leetcode98.驗證二叉搜尋樹演算法LeetCode二叉樹
- Leetcode 938. 二叉搜尋樹的範圍和(DAY 2)LeetCode
- 重建二叉樹[by Python]二叉樹Python
- 最優二叉樹(哈夫曼樹)Java實現二叉樹Java
- 比酒量問題與二叉樹搜尋和路徑問題二叉樹