1 leetcode654. 最大二叉樹
題目連結:654. 最大二叉樹 - 力扣(LeetCode)
文章連結:程式碼隨想錄
影片連結:又是構造二叉樹,又有很多坑!| LeetCode:654.最大二叉樹_嗶哩嗶哩_bilibili
思路:跟上一道題從中序後序中返回一個二叉樹,好了,同理的思路就做出來咯,哈哈哈哈哈哈
1.1 自己的程式碼
# 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 constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
if len(nums) == 0:
return None
root_val = max(nums)
root = TreeNode(root_val)
if len(nums) == 1:
return root
ind = 0
for i in range(len(nums)):
if nums[i] == root_val:
ind = i
break
nums_left = nums[:ind]
nums_right = nums[ind+1:]
root.left = self.constructMaximumBinaryTree(nums_left)
root.right = self.constructMaximumBinaryTree(nums_right)
return root
1.2影片後的思路
差異就是這個構造的二叉樹,因為一定有值,所以沒必要對其為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 constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
if len(nums) == 1:
return TreeNode(nums[0])
root = TreeNode(0)
maxval = 0
maxind = 0
for i in range(len(nums)):
if nums[i]>maxval:
maxval = nums[i]
maxind = i
root.val = maxval
if maxind>0:
root.left = self.constructMaximumBinaryTree(nums[:maxind])
if maxind<len(nums)-1:
root.right = self.constructMaximumBinaryTree(nums[maxind+1:])
return root
1.3 本題小結
- 這道題的第一種思路就是使用前序中序構造一個唯一的二叉樹,這麼做可以寫出來程式碼,但是會非常的冗餘
- 然後就是第二種遞迴,首先判斷什麼時候終止,就是這個二叉樹只有一個數值的時候,可以直接進行返回,這裡發現由於遞迴的原因,如果直接將資料使用
max
函式的話會直接報錯
2 leetcode617.合併二叉樹
題目連結:617. 合併二叉樹 - 力扣(LeetCode)
文章連結:程式碼隨想錄
影片連結:一起操作兩個二叉樹?有點懵!| LeetCode:617.合併二叉樹_嗶哩嗶哩_bilibili
思路:開始的時候,我想的是這個直接進行合併就行,但是發現有的二叉樹我連分開都不能分開,還是直接看影片來寫吧
2.1 影片後的思路
思路:
不進行新的二叉樹定義,覆蓋的方法,就是將另一個二叉樹的值加過去就好了,其實理論上真的沒新的,就是自己想不出來
2.1.1 覆蓋的方法
# 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 mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if root1==None:
return root2
if root2 == None:
return root1
root1.val += root2.val
root1.left = self.mergeTrees(root1.left,root2.left)
root1.right = self.mergeTrees(root1.right,root2.right)
return root1
2.1.2 定義一個新的二叉樹
# 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 mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if root1==None:
return root2
if root2 == None:
return root1
root = TreeNode(0)
root.val = root1.val +root2.val
root.left = self.mergeTrees(root1.left,root2.left)
root.right = self.mergeTrees(root1.right,root2.right)
return root
2.2 本題小結
- 寫到這裡的時候,我突然發現,這種題真的寫的不難,主要是思路上會有想不到的地方,每次卡殼了,但是聽影片聽了一點就會了
- 二叉樹合併其實和兩數相加也是同樣的原理,要學會舉一反三呀
3 leetcode700.二叉搜尋樹中的搜尋
題目連結:700. 二叉搜尋樹中的搜尋 - 力扣(LeetCode)
文章連結:程式碼隨想錄
影片連結:不愧是搜尋樹,這次搜尋有方向了!| LeetCode:700.二叉搜尋樹中的搜尋_嗶哩嗶哩_bilibili
思路:看到題目想使用前序遍歷,如果找到了這個值,那就可以返回這個樹了;但是吧寫的時候,不會了,,
3.1 基礎知識
二叉搜尋樹
二叉搜尋樹是一個有序樹:
- 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
- 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
- 它的左、右子樹也分別為二叉搜尋樹
3.2 影片後的思路
3.2.1 遞迴法
# 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 searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if root ==None or root.val == val:
return root
result = TreeNode(0)
if root.val <val:
result = self.searchBST(root.right,val)
if root.val >val:
result =self.searchBST(root.left,val)
return result
3.2.2 迭代法
# 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 searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
while root:
if root.val>val:
root = root.left
elif root.val<val:
root = root.right
else:
return root
3.3 本題小結
- 這道題首先是二叉搜尋樹的概念,左子樹永遠比根節點小,右子樹永遠比根節點大,根據這個思路往下寫就行了
- 對於遞迴而言,如果知道這個,就容易,不過目前沒徹底弄明白為什麼要賦值result
- 遞迴法,就是聽了會了,寫的時候懵了,看題解的時候徹底會了,有點聰明但不多哈哈哈哈哈哈哈
4 leetcode98.驗證二叉搜尋樹
題目連結:98. 驗證二叉搜尋樹 - 力扣(LeetCode)
文章連結:程式碼隨想錄
影片連結:你對二叉搜尋樹瞭解的還不夠! | LeetCode:98.驗證二叉搜尋樹_嗶哩嗶哩_bilibili
思路:哈哈哈哈哈哈,開始想的是如果左子樹和右子樹的值滿足二叉搜尋樹的情況,就可以返回True;結果寫的時候,根本不會寫,,
4.1 自己的程式碼
寫了一句有超級大問題的程式碼
if root.val>root.left.val and root.val<root.right.val:
return True
result = TreeNode(0)
這裡問題出在,只判斷了他的左右節點,沒有判斷左子樹和右子樹,二叉樹的概念有一些混淆!!!!
4.2 影片後的思路
看完了,但是怎麼說呢,感覺還是有一點點難度,寫起來有一點不知如何下手的感覺,,
重點:判斷這個問題的時候,其實很好的一個想法就是使用中序遍歷,因為這樣可以保證出來的值是從小到大排序的一個過程
4.2.1暴力搜尋法
這裡之前寫錯了一句話,非要先判斷正確的,後來發現其實上去對的可能在中間會出現錯誤,就會有問題。
# 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 isValidBST(self, root: Optional[TreeNode]) -> bool:
self.vec = []
self.traversal(root)
for i in range(len(self.vec)-1):
if self.vec[i]>=self.vec[i+1]:
return False
return True
def traversal(self,node):
if node ==None:
return True
self.traversal(node.left)
self.vec.append(node.val)
self.traversal(node.right)
4.2.2 使用極小值的方法
定義一個極值,然後就是在中序的時候比較當前值和極值的關係,做一個返回的操作
# 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.maxval = float('-inf')
def isValidBST(self, root: Optional[TreeNode]) -> bool:
if root == None:
return True
left = self.isValidBST(root.left)
if root.val>self.maxval:
self.maxval = root.val
else:
return False
right = self.isValidBST(root.right)
return left and right
4.2.3 雙指標的方法
這種方法就是定義一個前指標,然後比較前一個值和當前值的關係,如果遇到了不符合的就返回
# 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.pre = None
def isValidBST(self, root: Optional[TreeNode]) -> bool:
if root == None:
return True
left = self.isValidBST(root.left)
if self.pre !=None and self.pre.val>=root.val:
return False
self.pre = root
right = self.isValidBST(root.right)
return left and right
4.3 本題小結
- 本題的主要難點對我而言,就是上去思路就錯了,其次分析二叉樹的題目沒有嚴格按照遍歷順序去思考,導致這個題目花費了挺多時間的
- 思路上的總結,首先,這個是驗證,所以傳入的是這個二叉樹,終止條件找不正確的,然後第三部就是遞迴的內部邏輯,按照這個來就容易一些
- 記住使用的是中序遍歷方法
5 今日小結
- 前兩道題是對遞迴方法的一個總結吧,我覺得是,相比而言就是比較中規中矩的遞迴方法
- 後兩道題是對二叉搜尋樹概念的掌握和理解,在寫的過程越來越對這種概念理解的清晰了,題目思路也順暢了很多
- 希望接下來我可以真的自己分析題目,感覺現在的程式碼都是看了影片才會,離開影片可能就不會了,,,