- 任務
- 654. 最大二叉樹
- 思路
- 617. 合併二叉樹
- 思路
- 700.二叉搜尋樹中的搜尋
- 思路
- 98. 驗證二叉搜尋樹
- 思路(錯誤)
- 思路(正確)
- 654. 最大二叉樹
- 心得體會
任務
654. 最大二叉樹
給定一個不重複的整數陣列 nums 。 最大二叉樹 可以用下面的演算法從 nums 遞迴地構建:
建立一個根節點,其值為 nums 中的最大值。
遞迴地在最大值 左邊 的 子陣列字首上 構建左子樹。
遞迴地在最大值 右邊 的 子陣列字尾上 構建右子樹。
思路
做了昨天的利用前中序(或者中後)陣列構建二叉樹,就會做這道題,思路基本一致。按照演算法,分割陣列區域並建立即可。
class Solution:
def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
if len(nums)==0: return None
index = 0
maxValue = float('-inf')
for i in range(len(nums)):
if nums[i] > maxValue:
maxValue = nums[i]
index = i
root = TreeNode(nums[index])
leftNums = nums[:index]
rightNums = nums[index+1:]
root.left = self.constructMaximumBinaryTree(leftNums)
root.right = self.constructMaximumBinaryTree(rightNums)
return root
617. 合併二叉樹
想象一下,當你將其中一棵覆蓋到另一棵之上時,兩棵樹上的一些節點將會重疊(而另一些不會)。你需要將這兩棵樹合併成一棵新二叉樹。合併的規則是:如果兩個節點重疊,那麼將這兩個節點的值相加作為合併後節點的新值;否則,不為 null 的節點將直接作為新二叉樹的節點。
返回合併後的二叉樹。
思路
單層遞迴邏輯: 分情況合併當前節點
- 兩樹都不存在節點
- 兩樹只有一個存在,則返回有的那個
- 都存在,則將節點和相加並構建成新節點,並且分別遞迴的合併其左右子樹
這道題也是結合了遍歷過程和傳統遞迴的思路
class Solution:
def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if not root1 and not root2: return None
if root1 and not root2: return root1
if not root1 and root2: return root2
if root1 and root2:
newRoot = TreeNode(root1.val + root2.val)
newRoot.left = self.mergeTrees(root1.left,root2.left)
newRoot.right = self.mergeTrees(root1.right,root2.right)
return newRoot
700.二叉搜尋樹中的搜尋
思路
這道題很簡單,遞迴的思路就是遍歷節點,找到就返回,否則根據條件向相應的子樹去找。
迭代的思路是,val較小就往當前節點左子樹找,val較大就往當前節點的右子樹找,直到找到或者到達None.
# 遞迴法
class Solution:
def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if not root: return None
if root.val == val: return root
if val < root.val: return self.searchBST(root.left,val)
else: return self.searchBST(root.right,val)
# 迭代法
class Solution:
def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
while root:
if val < root.val: root = root.left
elif val > root.val: root = root.right
else: return root
return None
98. 驗證二叉搜尋樹
給你一個二叉樹的根節點 root ,判斷其是否是一個有效的二叉搜尋樹。
有效 二叉搜尋樹定義如下:
節點的左
子樹
只包含 小於 當前節點的數。
節點的右子樹只包含 大於 當前節點的數。
所有左子樹和右子樹自身必須也是二叉搜尋樹。
思路(錯誤)
想當然的解法是直接用遞迴,判斷當前節點的區域性邏輯是否滿足(它比它右節點小,比它左節點大),然後再判斷左右子樹是否滿足,全部滿足則返回True。可惜這種思路是錯誤的。。反例 [5,4,6,null,null,3,7], 某節點必須比他的左子樹所有的值小,右子樹所有的值大。這個7大於了根節點的大小,違反了BST的定義
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
if not root: return True
elif not root.left and not root.right: return True
elif root.left and not root.right:
if root.val > root.left.val: return True
else:return False
elif not root.left and root.right:
if root.val < root.right.val: return True
else:return False
else:
if root.val > root.left.val and root.val < root.right.val:
return self.isValidBST(root.left ) and self.isValidBST(root.right)
else:
return False
思路(正確)
判斷中序序列是否有序
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
lst = []
self.inorder(root,lst)
print(lst)
for i in range(len(lst)-1):
if lst[i] >= lst[i+1]: return False
return True
def inorder(self,root,lst):
if not root: return None
self.inorder(root.left,lst)
lst.append(root.val)
self.inorder(root.right,lst)
心得體會
更嫻熟的掌握了單純遞迴邏輯(區域性+遞迴),以及遞迴序遍歷流程的思路。