235. 二叉搜索树的最近公共祖先
题目链接: 235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:二叉搜索树找祖先就有点不一样了!| 235. 二叉搜索树的最近公共祖先
思路
- 相比二叉树的最近公共祖先问题,因为二叉搜索树自带方向性,可以方便的从上向下查找目标区间,遇到目标区间内的节点,直接返回。
递归
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if root.val > p.val and root.val > q.val:
return self.lowestCommonAncestor(root.left,p,q)
elif root.val < p.val and root.val < q.val:
return self.lowestCommonAncestor(root.right,p,q)
else:
return root
迭代
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
while root:
if root.val > p.val and root.val > q.val:
root = root.left
elif root.val < p.val and root.val < q.val:
root = root.right
else: # q,p分别在root左右子数的情况,和root是q或p的情况
return root
701.二叉搜索树中的插入操作
题目链接: 701.二叉搜索树中的插入操作 - 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:原来这么简单? | LeetCode:701.二叉搜索树中的插入操作
递归
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if not root:
return TreeNode(val)
if root.val > val:
root.left = self.insertIntoBST(root.left,val)
if root.val < val:
root.right = self.insertIntoBST(root.right,val)
return root
迭代
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if not root:
return TreeNode(val)
node = root
while node:
if node.val > val:
if node.left:
node = node.left
else:
node.left = TreeNode(val)
break
if node.val < val:
if node.right:
node = node.right
else:
node.right = TreeNode(val)
break
return root
450.删除二叉搜索树中的节点
题目链接: 450.删除二叉搜索树中的节点- 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:调整二叉树的结构最难!| LeetCode:450.删除二叉搜索树中的节点
思路
- 使用递归函数的返回值来完成把节点从二叉树中移除的操作
- 二叉搜索树中删除节点有以下五种情况:
(1)第一种情况:没找到删除的节点,遍历到空节点直接返回了
【之后的情况都是找到删除的节点】
(2)第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
(3)第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
(4)第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
(5)第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
递归
class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
# 第一种情况:没找到删除的节点,遍历到空节点直接返回了
if not root:
return root
if root.val > key:
root.left = self.deleteNode(root.left,key)
elif root.val < key:
root.right = self.deleteNode(root.right,key)
else:
if not root.left and not root.right: # 第二种情况 左右孩子都为空,返回NULL
return None
elif not root.left: # 第三种情况 左孩子都为空,返回右孩子
return root.right
elif not root.right: # 第四种情况 右孩子都为空,返回左孩子
return root.left
else: # 第五种情况 左右孩子不为空,将左孩子放到右孩子最左边的下面,返回右孩子
cur = root.right
while cur.left:
cur = cur.left
cur.left = root.left
return root.right
return root
迭代
class Solution:
def deleteOneNode(self, root):
if not root.left and not root.right:
return None
elif not root.left:
return root.right
elif not root.right:
return root.left
else:
cur = root.right
while cur.left:
cur = cur.left
cur.left = root.left
return root.right
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
if not root:
return root
pre = None
cur = root
while cur:
if cur.val == key:
break
pre = cur
if cur.val > key:
cur = cur.left
else:
cur = cur.right
if not pre:
return self.deleteOneNode(cur)
else:
if pre.left and pre.left.val == key:
pre.left = self.deleteOneNode(cur)
elif pre.right and pre.right.val == key:
pre.right = self.deleteOneNode(cur)
return root
1588

被折叠的 条评论
为什么被折叠?



