235. 二叉搜索树的最近公共祖先
代码随想录:235. 二叉搜索树的最近公共祖先
Leetcode:235. 二叉搜索树的最近公共祖先
做题
简单回顾了一下基本的方法,具体见Day21的236. 二叉树的最近公共祖先。然后利用二叉搜索树的性质调试一下,重点是考虑p为q祖先的情况。我采用的方法是先做排序,找出较大值和较小值,再搜索。
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if p.val < q.val:
p, q = q, p
if root.val <= p.val and root.val >= q.val:
return root
elif root.val > p.val:
return self.lowestCommonAncestor(root.left, p, q)
elif root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
看文章
思路类似,只是判断逻辑有点不同。这里展示一下迭代法:
class Solution:
def lowestCommonAncestor(self, root, p, q):
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:
return root
return None
701.二叉搜索树中的插入操作
代码随想录:701.二叉搜索树中的插入操作
Leetcode:701.二叉搜索树中的插入操作
做题
思路不难,但要静下心想想。这次用的是迭代的思路。
# 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]:
start = root
if not root:
return TreeNode(val)
while root:
if val < root.val:
if root.left is None:
node = TreeNode(val)
root.left = node
break
root = root.left
else:
if root.right is None:
node = TreeNode(val)
root.right = node
break
root = root.right
return start
看文章
这道题好像用递归的思路比较多,但我感觉我的迭代方法也挺简单。下面放一个递归的代码例子:
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if root is None or root.val == val:
return TreeNode(val)
elif root.val > val:
if root.left is None:
root.left = TreeNode(val)
else:
self.insertIntoBST(root.left, val)
elif root.val < val:
if root.right is None:
root.right = TreeNode(val)
else:
self.insertIntoBST(root.right, val)
return root
450.删除二叉搜索树中的节点
代码随想录:450.删除二叉搜索树中的节点
Leetcode:450.删除二叉搜索树中的节点
做题
尝试按之前701的逻辑写,但越写越多,bug也还是有,只能通过测试用例。
看文章
有以下五种情况:
- 没找到删除的节点,遍历到空节点直接返回了;
- 左右孩子都为空(叶子节点),直接删除节点, 返回None为根节点;
- 删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点;
- 删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点;
- 左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。这是容易被忽略的情况。
具体实现代码如下:
class Solution:
def deleteNode(self, root, key):
if root is None:
return root
if root.val == key:
if root.left is None and root.right is None:
return None
elif root.left is None:
return root.right
elif root.right is None:
return root.left
else:
cur = root.right
while cur.left is not None:
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
以往忽略的知识点小结
- 删除二叉搜素树的节点是难题,需要考虑完整情况。
个人体会
完成时间:2h50min。
心得:前面两道还好,主要是删除二叉搜素树的节点,需要想清楚所有情况。