昨天端午gap了一天,今天繼續。
之前都是零散地做題,感覺缺乏體系,今天開始就著labuladong的演算法小抄來做題,順便記下自己的閱讀筆記。
核心套路篇1
首先是第一章,核心套路篇,這一章主要介紹演算法解題的通用思路。
資料結構的核心是陣列和連結串列,其它都是基於此二者的變體。
資料結構操作就是增刪改查四種,操作物件具體分為陣列、連結串列以及二叉樹三種框架。實際上,二叉樹的遍歷就是連結串列遍歷的擴充。
作者說,刷題先刷二叉樹,因為二叉樹最能培養框架思維,實現一通百通。
二叉樹中的最大路徑和
題目描述:路徑和是路徑中各節點值的總和。給你一個二叉樹的根節點 root ,返回其最大路徑和。
示例:
輸入:root = [1,2,3]
輸出:6
解釋:最優路徑是 2 -> 1 -> 3 ,路徑和為 2 + 1 + 3 = 6
輸入:root = [-10,9,20,null,null,15,7]
輸出:42
解釋:最優路徑是 15 -> 20 -> 7 ,路徑和為 15 + 20 + 7 = 42
問題
- 這裡只給出了樹的序列化陣列,是不是還要先還原成二叉樹呢?
不,實際上程式碼中已經給出了樹的根節點 - 要求出最大路徑,是不是要用動態規劃或者回溯呢?
不,只需要每一步進行貪心求解。
思路核心 - 遞迴
- 自己加左右子樹的路徑就是一條路徑/自己作為路徑的一部分時就只能選擇左右子樹的其中一個
- 怎麼樣能比較左右子樹的最大值呢,那當然是先遍歷它們,再進行比較,這就是後序遍歷
- 用一個變數記錄下全域性的最大值即可
注意 - 這裡的最大路徑變數需要是全域性變數
- 獲得左右子樹路徑和時,需要與0做個max,因為只有大於0的路徑才對總和有意義
- 每次計算經過自己的左右子節點(若小於0則不經過)以及自己時的路徑
- 返回時只能選擇一邊加自己返回
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
# 以上給出了樹的定義
class Solution:
def __init__(self):
# 初始化為最小值,用於記錄最大路徑和
self.max_sum = -inf
def maxPathSum(self, root: Optional[TreeNode]) -> int:
# 獲得root節點對應樹的最大路徑和
self.getMaxPathSum(root)
return self.max_sum
# 定義遞迴函式
def getMaxPathSum(self, root):
# 處理邊界條件
if root==None:
return 0
left = max(0, self.getMaxPathSum(root.left))
right = max(0, self.getMaxPathSum(root.right))
self.max_sum = max(self.max_sum,root.val+left+right)
return max(left,right) + root.val