代码随想录算法训练营第二十二天|235. 二叉搜索树的最近公共祖先,701. 二叉搜索树中的插入操作,450. 删除二叉搜索树中的节点
235. 二叉搜索树的最近公共祖先
[注意]
1.因为是有序树,所以如果中间节点是 q 和 p 的公共祖先,那么中间节点的数组 一定是在[p, q]区间的。即中节点 > p && 中节点 < q 或者 中节点 > q && 中节点 < p。
2.那么只要从上到下去遍历,遇到 cur节点是数值在[p, q]区间中则一定可以说明该节点cur就是q 和 p的公共祖先。
3.遍历顺序无所谓,没有中间处理逻辑,只要有一个左一个右就可以.
[代码]
1 # Definition for a binary tree node. 2 # class TreeNode(object): 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution(object): 9 def lowestCommonAncestor(self, root, p, q): 10 """ 11 :type root: TreeNode 12 :type p: TreeNode 13 :type q: TreeNode 14 :rtype: TreeNode 15 """ 16 #1.递归法 17 #左 18 if root.val > p.val and root.val > q.val: 19 return self.lowestCommonAncestor(root.left, p, q) 20 #右 21 if root.val < p.val and root.val < q.val: 22 return self.lowestCommonAncestor(root.right, p, q) 23 #cur处在中间 24 return root 25 26 #2.迭代法 27 while True: 28 if root.val > p.val and root.val > q.val: 29 root = root.left 30 elif root.val < p.val and root.val < q.val: 31 root = root.right 32 else: 33 return root
701. 二叉搜索树中的插入操作
[注意]
1.只要遍历二叉搜索树,找到空节点 插入元素就可以了,
2.把添加的节点返回给上一层,就完成了父子节点的赋值操作了,
[代码]
1 # Definition for a binary tree node. 2 # class TreeNode(object): 3 # def __init__(self, val=0, left=None, right=None): 4 # self.val = val 5 # self.left = left 6 # self.right = right 7 class Solution(object): 8 def insertIntoBST(self, root, val): 9 """ 10 :type root: TreeNode 11 :type val: int 12 :rtype: TreeNode 13 """ 14 # 返回更新后的以当前root为根节点的新树,方便用于更新上一层的父子节点关系链 15 16 # Base Case 17 if not root: return TreeNode(val) 18 19 # 单层递归逻辑: 20 if val < root.val: 21 # 将val插入至当前root的左子树中合适的位置 22 # 并更新当前root的左子树为包含目标val的新左子树 23 root.left = self.insertIntoBST(root.left, val) 24 25 if root.val < val: 26 # 将val插入至当前root的右子树中合适的位置 27 # 并更新当前root的右子树为包含目标val的新右子树 28 root.right = self.insertIntoBST(root.right, val) 29 30 # 返回更新后的以当前root为根节点的新树 31 return root
450. 删除二叉搜索树中的节点
[注意]
1.删除操作通过返回值进行操作,在停止条件里进行处理.
2.有以下五种情况:
- 第一种情况:没找到删除的节点,遍历到空节点直接返回了
- 找到删除的节点
- 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
- 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
- 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
- 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点.
- [代码]
-
1 # Definition for a binary tree node. 2 # class TreeNode(object): 3 # def __init__(self, val=0, left=None, right=None): 4 # self.val = val 5 # self.left = left 6 # self.right = right 7 class Solution(object): 8 def deleteNode(self, root, key): 9 """ 10 :type root: TreeNode 11 :type key: int 12 :rtype: TreeNode 13 """ 14 #1.递归法 15 if not root:#根节点为空,情况1 16 #第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回None为根节点 17 return None 18 #向右遍历 19 if key > root.val: 20 root.right = self.deleteNode(root.right, key) 21 #向左 22 elif key < root.val: 23 root.left = self.deleteNode(root.left, key) 24 25 else: 26 #第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点 27 if not root.left: 28 return root.right 29 30 #第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点 31 32 if not root.right: 33 return root.left 34 35 # 情况五:左右子树都不为空,找到右孩子的最左节点 记为node 36 node = root.right 37 while node.left:#右孩子左节点不为空,一直遍历 38 node = node.left 39 # 将当前节点的左子树挂在node的左孩子上 40 node.left = root.left 41 # 当前节点的右子树替换掉当前节点,完成当前节点的删除 42 root = root.right 43 44 return root
浙公网安备 33010602011771号