题目:二叉搜索树最近的公共祖先
题解:
1)和二叉树的最近公共祖先不同,这道题更巧妙。转化为找到在**[p,q]区间内的节点**,如果找到就返回该节点,如果没找到就返回None(但是最终一定会找到,因为题目中说二叉树中一定存在待寻找的节点。
2)p,q的大小不一定
3) 注意:搜索一条路径和搜索整颗树的区别。如果是搜索整棵树,应该在两个递归之后再返回值;搜索一条路径的话应该递归后直接返回。
代码:
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
if not root:
return root
if root.val > p.val and root.val > q.val:
left = self.lowestCommonAncestor(root.left, p, q)
# if left:
# return left
return left
if root.val < p.val and root.val < q.val:
right = self.lowestCommonAncestor(root.right, p, q)
# if right:
# return right
return right
if (p.val<=root.val and q.val >= root.val) or (q.val<=root.val and p.val >= root.val):
return root
题目:二叉搜索树中的插入操作
题解:
1)这道题中的插入操作其实都可以转化为找到一个叶子节点的空子节点去插入。
2)思考终止条件:当遇到一个空节点的时候适合去插入一个新节点,因此每次遇到空指针都可以新建一个节点,然后返回给它的父节点。
3)思考返回值:因为最终要返回一个插好的二叉树的根节点,因此要返回root
4) 使用递归函数的返回值的方式增加节点
代码:
class Solution(object):
def insertIntoBST(self, root, val):
"""
:type root: TreeNode
:type val: int
:rtype: TreeNode
"""
if not root:
temp = TreeNode(val = val)
return temp
if val > root.val:
root.right = self.insertIntoBST(root.right, val)
if val < root.val:
root.left = self.insertIntoBST(root.left, val)
return root
题目:删除二叉搜索树中的节点
题解:
1)删除节点涉及到更改二叉树的结构(相比增加从节点来说)
2) 要思考有几种情况:没找到要删除的节点;要删除的是叶子节点;要删除的节点有左孩子没有右孩子;有右孩子没有左孩子;有左右孩子(这种情况将右孩子/左孩子设成新根节点都是可以的。比如选择右孩子,那么要找到右子树中最左侧,也就是数值最小的节点的左子树,用来承接原来的左子树)。
3)对于返回值,返回的应该是删除节点之后的根节点。
代码:
class Solution(object):
def deleteNode(self, root, key):
"""
:type root: TreeNode
:type key: int
:rtype: TreeNode
"""
if not root:
return None
if root.val == key:
if not root.right and not root.left:
return None
elif not root.right and root.left:
return root.left
elif not root.left and root.right:
return root.right
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