dreamweaver網(wǎng)站建設(shè)教程新網(wǎng)站怎么推廣
235. 二叉搜索樹(shù)的最近公共祖先 - 力扣(LeetCode)
在一個(gè)二叉搜索樹(shù)中,兩個(gè)節(jié)點(diǎn) p 和 q 的最近公共祖先可以通過(guò)以下的算法找到:
- 從根節(jié)點(diǎn)開(kāi)始。
- 如果當(dāng)前節(jié)點(diǎn)的值大于 p 和 q 的值,那么你需要轉(zhuǎn)向左子樹(shù)。因?yàn)樵诙嫠阉鳂?shù)中,左子樹(shù)的所有節(jié)點(diǎn)的值都比當(dāng)前節(jié)點(diǎn)的值小。
- 如果當(dāng)前節(jié)點(diǎn)的值小于 p 和 q 的值,那么你需要轉(zhuǎn)向右子樹(shù)。因?yàn)樵诙嫠阉鳂?shù)中,右子樹(shù)的所有節(jié)點(diǎn)的值都比當(dāng)前節(jié)點(diǎn)的值大。
- 如果以上條件都不滿足,那么當(dāng)前節(jié)點(diǎn)就是 p 和 q 的最近公共祖先。
在 Python 中,這個(gè)算法可以像這樣實(shí)現(xiàn):
class TreeNode:def __init__(self, x):self.val = xself.left = Noneself.right = Nonedef lowestCommonAncestor(root, p, q):while root:if root.val > p.val and root.val > q.val:root = root.leftelif root.val < p.val and root.val < q.val:root = root.rightelse:return rootreturn None
在這個(gè)代碼中,lowestCommonAncestor
函數(shù)將接受一個(gè)二叉搜索樹(shù)的根節(jié)點(diǎn) root
,和兩個(gè)需要找最近公共祖先的節(jié)點(diǎn) p
和 q
。然后它將返回 p 和 q 的最近公共祖先。如果沒(méi)有找到,那么它將返回 None。
注意這個(gè)算法假設(shè) p 和 q 都在這棵二叉搜索樹(shù)中。
701. 二叉搜索樹(shù)中的插入操作 - 力扣(LeetCode)
因?yàn)槭嵌鏄?shù),直接按照規(guī)則遍歷,然后在對(duì)應(yīng)葉子結(jié)點(diǎn)插入
# 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 insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:if root is None:return TreeNode(val)pre = Nonedef traversal(cur, val, left_child=False):nonlocal preif cur is None:if left_child:pre.left = TreeNode(val)else:pre.right = TreeNode(val)returnpre = curif cur.val > val:traversal(cur.left, val, left_child=True)else:traversal(cur.right, val)traversal(root, val)return root
下面是GPT4對(duì)該代碼的優(yōu)化
你的代碼已經(jīng)很好地實(shí)現(xiàn)了插入操作。你在遍歷樹(shù)的時(shí)候,遞歸地找到插入節(jié)點(diǎn)的位置,然后創(chuàng)建新節(jié)點(diǎn)并插入到正確的位置。同時(shí),你用一個(gè)外部變量
pre
來(lái)跟蹤上一個(gè)節(jié)點(diǎn),以便在正確的位置插入新節(jié)點(diǎn)。然而,你的代碼可以被優(yōu)化,使其更簡(jiǎn)潔和易于理解。在優(yōu)化后的代碼中,你可以使用返回值,而不是外部變量來(lái)跟蹤插入的位置。這樣,你可以避免使用
nonlocal
關(guān)鍵字,并使函數(shù)的邏輯更加清晰。以下是優(yōu)化后的代碼:# 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 insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:if root is None:return TreeNode(val)if root.val > val:root.left = self.insertIntoBST(root.left, val)else:root.right = self.insertIntoBST(root.right, val)return root ```在優(yōu)化后的代碼中,插入新節(jié)點(diǎn)的邏輯被分配給遞歸調(diào)用的返回值,這使得代碼更加簡(jiǎn)潔并且邏輯更加清晰。這個(gè)函數(shù)將創(chuàng)建一個(gè)新的 `TreeNode` 如果 `root` 是 `None`,否則它將遞歸地遍歷左子樹(shù)或右子樹(shù),根據(jù) `val` 的值決定向哪個(gè)方向遍歷。然后,遞歸調(diào)用的返回值(即新節(jié)點(diǎn)或現(xiàn)有節(jié)點(diǎn))被分配給 `root.left` 或 `root.right`,從而實(shí)現(xiàn)插入操作。最后,函數(shù)返回 `root`,它現(xiàn)在可能有一個(gè)新的子節(jié)點(diǎn)。
450. 刪除二叉搜索樹(shù)中的節(jié)點(diǎn) - 力扣(LeetCode)
對(duì)于二叉搜索樹(shù)的刪除操作,主要分為以下幾個(gè)步驟:
- 找到需要?jiǎng)h除的節(jié)點(diǎn);
- 如果節(jié)點(diǎn)是葉子節(jié)點(diǎn),可以直接刪除;
- 如果節(jié)點(diǎn)只有一個(gè)孩子,可以直接將其父節(jié)點(diǎn)的相應(yīng)鏈接指向它的孩子;
- 如果節(jié)點(diǎn)有兩個(gè)孩子,需要找到其右子樹(shù)的最小節(jié)點(diǎn)(或左子樹(shù)的最大節(jié)點(diǎn)),用這個(gè)節(jié)點(diǎn)代替要?jiǎng)h除的節(jié)點(diǎn),然后刪除這個(gè)最小(或最大)節(jié)點(diǎn)。
以下是一個(gè)用Python實(shí)現(xiàn)的例子:
# 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 = rightclass Solution:def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:if not root:return Noneif key < root.val: # key在左子樹(shù)root.left = self.deleteNode(root.left, key)elif key > root.val: # key在右子樹(shù)root.right = self.deleteNode(root.right, key)else: # 找到key,進(jìn)行刪除操作if not root.left: # 左子樹(shù)為空,直接返回右子樹(shù)return root.rightif not root.right: # 右子樹(shù)為空,直接返回左子樹(shù)return root.leftelse: # 左右子樹(shù)均不為空min_node = self.findMin(root.right) # 找到右子樹(shù)的最小節(jié)點(diǎn)root.val = min_node.val # 將最小節(jié)點(diǎn)的值復(fù)制到rootroot.right = self.deleteNode(root.right, min_node.val) # 刪除右子樹(shù)中的最小節(jié)點(diǎn)return rootdef findMin(self, node: Optional[TreeNode]) -> Optional[TreeNode]:# 找到樹(shù)中的最小節(jié)點(diǎn)while node.left:node = node.leftreturn node
這個(gè)函數(shù)的思路主要是使用遞歸來(lái)找到要?jiǎng)h除的節(jié)點(diǎn),然后按照上面提到的規(guī)則刪除。在這個(gè)過(guò)程中,我們使用了一個(gè)輔助函數(shù) findMin
來(lái)找到一個(gè)樹(shù)中的最小節(jié)點(diǎn)。
總結(jié)
今天的題主要是將結(jié)點(diǎn)作為返回值,通過(guò)遍歷過(guò)程中更新左右子樹(shù)來(lái)完成對(duì)樹(shù)的操作