LeetCode #98 Validate Binary Search Tree - 刷題之旅
1 題目描述
2 解法
我的問題是在,我一開始以為,只要把上一個節點,傳下去,跟下一層的節點進行比較就好了。但是我錯了!
我一開始腦子想著
你會發現上圖根本不是正確的二元搜尋樹,因為節點3比root小,不應該出現在右子樹中…所以我就卡住了。
2.2 使用Recursion
其實這題真的目的在於,在 左子樹,只要一往右走,就要考慮到根節點的值,不能大於root.val。而在右子樹,只要一往右走,就要考慮到根節點的值,不能小於root.val。我想了好久,都沒想到到底要怎麼樣知道走不同子樹的路線時(在左子樹還是在右子樹),還能知道當前到底走在哪個方向(一往右走,還是一往左走)…直到我試著畫出每個節點的上下限。
你會發現,根本不需要顧慮左還是右子樹,你會發現:
- 只要是往左走,
max
一定會更新成parent.val
,而min
則是繼承自上一層的min
。 - 只要是往右走,
min
一定會更新成parent.val
,而max
則是繼承自上一層的max
。
然後神奇的事情發生了:
- 因為在左子樹往右走時,
max
會一路繼承上一層的max
,追溯到源頭就是root
! 也就是說,我們在左子樹往右走時,max
一定會是root
的值。 - 因為在右子樹往左走時,
min
會一路繼承上一層的min
,追溯到源頭就是root
! 也就是說,我們在右子樹往左走時,min
一定會是root
的值。
寫成python其實就是這樣:
1 |
|
那我們接下來考慮一下我們的終止條件:
- 確保當前節點的值在上下限之間
- 如果挖到底,就回傳True
1 | def isValidBST(self, node: Optional[TreeNode], min_val=float('-inf'), max_val=float('inf')) -> bool: |
2.3 使用Stack
我們也可以考慮使用inorder來解這題,因為inorder是一個遞增的序列,(左 - 中 - 右)我們可以透過 inorder 搭配 stack,把所有節點都走過一遍,並且確保是遞增的序列。每次在pop()出來的時候,我們就可以確保右邊的節點比當前節點大。如果不是就回傳False。
首先,一步步把左邊塞入stack
1 | def isValidBST(self, root: Optional[TreeNode]) -> bool: |
到最底後,pop()出來,開始確保right比node大
1 | def isValidBST(self, root: Optional[TreeNode]) -> bool: |
3 總結
這題我沒有想出來,缺乏考慮到在二元搜尋樹在左子樹往右走時,還要考慮到root,而在右子樹往左走時,也要考慮到root。而最難的問題是,怎麼在適當的時幾,考慮到root?要怎麼把root一層層傳下去是關鍵。透過上下限的方式來看到共通性很重要。
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Shannon's Blog 🐟 技術 | 生活 | 旅行! 如果你覺得我的文章有幫助,希望你可以到我的 github 給我一個 star ⭐️ Shannon Blog Repo
評論