0124. Binary Tree Maximum Path Sum - chasel2361/leetcode GitHub Wiki

***Given a non-empty binary tree, find the maximum path sum.
For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections.
The path must contain at least one node and does not need to go through the root.

Example 1:
Input: [1,2,3]
Output: 6

Example 2:
Input: [-10,9,20,null,null,15,7]
Output: 42

一開始我題目沒看清楚,以為是要從根開始找最大的路徑和,還想說這個難度也可以叫做 hard 喔,明明就不難啊,只要在分支上先比較左右子樹的大小,往大的那邊加過去就可以了,寫出來的程式碼長這樣

class Solution:
    def __init__(self):
        self.total = 0
    def maxPathSum(self, root: TreeNode) -> int:
        if not root: return 0
            
        self.total += root.val
        if not root.left and not root.right:
            return self.total
        if not root.left and root.right:
            self.maxPathSum(root.right)
        if not root.right and root.left:
            self.maxPathSum(root.left)
                
        if root.left.val > root.right.val:
            self.maxPathSum(root.left)
        else:
            self.maxPathSum(root.right)
        return self.total

結果試跑一遍後才發現是任選兩個點找最大路徑和,靠北


如果我們要找兩個節點間的路徑和,這個路徑必定經過他們兩個共同的最低祖先節點 (或稱中繼點),最大路徑和就會是:

    max(中繼點值, 左子樹最大路徑和 + 中繼點, 右子樹最大路徑和 + 中繼點值, 三者總和)

所以只要用遞迴的方式依序比較每個節點,遇到更大的就更新,便可以解決這個問題。不過另一個問題是,左子樹以及右子樹的最大路徑和該怎麼計算出來呢?
可以這樣表示:

    max(節點值, 左子樹最大路徑和 + 節點值, 右子樹最大路徑和 + 節點值)

使用這些概念後寫出來的程式碼會長這樣

[1] 紀錄此節點不為中繼點時的最大路徑和
[2] 比較此節點為與不為中繼點時的最大路徑和,以及目前最大路徑和
[3] 回傳不為中繼點時的最大路徑和

class Solution:
    def __init__(self):
        self.res = 0
            
    def maxPathSum(self, root: TreeNode) -> int:
        if not root: return 0
        self.res = root.val
        self.dfs(root)
        return self.res
        
    def dfs(self, node):
        l = self.dfs(node.left) if node.left else 0
        r = self.dfs(node.right) if node.right else 0
        m = max(node.val, node.val + l, node.val + r)  #[1]
        self.res = max(self.res, m, l + r + node.val)  # [2]
        return m  # [3]

由於這個遞迴函式會一路優先往深層走,所以會稱為深度優先搜尋 (DFS, DeepFirst search)

這個寫法的時間複雜度以及空間複雜度都是 O(N)

  • 最糟的時候要從最左下比較最右下才會出現最大值,遞迴的層數為N