235. 二叉搜索树的最近公共祖先
在有序树里,如果判断一个节点的左子树里有p,右子树里有q呢?
因为是有序树,所以只要从上到下去遍历,遇到cur的左子树和右子树分别有p和q的时候说明找到了公共祖先。 那问题来了,一定是最近公共祖先吗?答案是是的,因为再多往下走一步一定会造成不包含p或者不包含q
如果遇到了p q都大于cur的情况,则搜索右子树;反之搜索左子树;
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if root is None:
return None # 搜索到叶子节点也没有pq说明没有搜到
if root.val > p.val and root.val >q.val:
left = self.lowestCommonAncestor(root.left, p, q)
if left: # 如果是none以外的值说明搜索到了公共祖先
return left
if root.val < p.val and root.val <q.val:
right = self.lowestCommonAncestor(root.right, p, q)
if right:
return right
else:
return root
701.二叉搜索树中的插入操作
其实这道题是比较简单的,因为插入节点这个事情不需要改变二叉树的结构,只需要在叶子节点插入即可,二叉搜索树仍然可以利用性质
递归三部曲:
- 确定传入参数和返回值:传入当前节点cur,需要插入的值value;最终返回节点
- 终止条件:遇到空节点时说明是插入位置,return new treenode
- 单层逻辑:判断当前cur与value的大小,cur→val小于value说明要去right子树找,大于要去left子树找,最终return root即可
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if root is None:
return TreeNode(val)
if root.val < val:
root.right = self.insertIntoBST(root.right, val)
if root.val > val:
root.left = self.insertIntoBST(root.left, val)
return root
450.删除二叉搜索树中的节点(难)
题意:给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
有五种情况:
-
第一种情况:没找到删除的节点,遍历到空节点直接返回了
-
找到删除的节点
- 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
- 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
- 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
- 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
# 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 deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]: if root is None: return None if root.val == key: if not root.left and not root.right: return None elif not root.left and root.right: return root.right elif root.left and not root.right: return root.left else: cur = root.right while cur.left: # 确保不为空,这是犯错的地方 cur = cur.left cur.left = root.left return root.right if root.val > key: root.left = self.deleteNode(root.left, key) if root.val < key: root.right = self.deleteNode(root.right, key) return root