235. 二叉搜索树的最近公共祖先
递归
思路:
1.确定递归函数参数以及返回值:输入root、q、p,输出最近公共祖先
2.确定终止条件:节点为空,返回
3.确定单层递归的逻辑:
-
如果当前节点的值大于
p
、q
的值,说明p
和q
应该在当前节点的左子树,因此将当前节点移动到它的左子节点,继续遍历; -
如果当前节点的值小于
p
、q
的值,说明p
和q
应该在当前节点的右子树,因此将当前节点移动到它的右子节点,继续遍历; -
如果当前节点不满足上面两种情况,则说明
p
和q
分别在当前节点的左右子树上,则当前节点就是分岔点,直接返回该节点即可。
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)
if root.val < p.val and root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
return root
迭代法
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
while True:
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:
return root
701.二叉搜索树中的插入操作
递归
思路:
1.确定递归函数参数以及返回值:输入root,val,返回新的root
2.确定终止条件:节点为空,插入val
3.确定单层递归的逻辑:
-
从根节点root开始向下递归遍历。根据val值和root.val的大小关系:
如果val < root.val,则应在当前节点的左子树继续遍历判断。
- 如果左子树为空,则新建节点,赋值为 val。链接到该子树的父节点上。并停止遍历。
- 如果左子树不为空,则继续向左子树移动。
如果val > root.val,则应在当前节点的右子树继续遍历判断。
- 如果右子树为空,则新建节点,赋值为 val。链接到该子树的父节点上。并停止遍历。
- 如果右子树不为空,则继续向左子树移动。
-
遍历完返回根节点
root
。
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
newNode = TreeNode(val)
if not root:
return newNode
if not root.left and val < root.val:
root.left = newNode
if not root.right and val > root.val:
root.right = newNode
if val < root.val:
self.insertIntoBST(root.left, val)
if val > root.val:
self.insertIntoBST(root.right, val)
return root
450.删除二叉搜索树中的节点
递归
思路:
1.从根节点root开始,递归遍历搜索二叉树。
2.当root为None,返回
-
如果root.val>key,则去左子树中搜索并删除,root.left 递归更新,递归完成后返回当前节点。
-
如果root.val<key,则去右子树中搜索并删除,root.right 递归更新,递归完成后返回当前节点。
-
如果root.val==key,则该节点就是待删除节点。
- 如果root.left为空,则删除该节点之后,则root.right代替当前节点位置,返回右子树。
- 如果root.right为空,则删除该节点之后,则root.left代替当前节点位置,返回左子树。
- 如果root.left和right都存在,则将root.left转移到root.right最左侧的叶子节点位置上,然后root.right代替当前节点位置。返回右子树。
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:
return root.right
elif not root.right:
return root.left
else:
# 左右子树都不为空,找到右孩子的最左节点,cur
cur = root.right
while cur.left:
cur = cur.left
# 将当前节点的左子树挂在cur的左孩子上
cur.left = root.left
# 当前节点的右子树替换掉当前节点,完成当前节点的删除
root = root.right
return root