Day22 | 二叉树

68 阅读1分钟

235. 二叉搜索树的最近公共祖先

递归法

注意同时判断p和q大小

def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
            
    def search(root):
        if not root:
            return
        if root == p or root == q:
            return root
        
        # BST的性质
        if root.val > p.val and root.val > q.val:
            return search(root.left)
        if root.val < q.val and root.val < p.val:
            return search(root.right)
        return root
    
    return search(root)

迭代法

(补)

701. 二叉搜索树中的插入操作

直接按照二叉搜索树的规则去遍历,遇到空节点就插入节点

    def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
        # 返回更新后的以当前root为根节点的新树,方便用于更新上一层的父子节点关系链

        # Base Case
        if not root: return TreeNode(val)

        # 单层递归逻辑:
        if val < root.val: 
            # 将val插入至当前root的左子树中合适的位置
            # 并更新当前root的左子树为包含目标val的新左子树
            root.left = self.insertIntoBST(root.left, val)

        if root.val < val:
            # 将val插入至当前root的右子树中合适的位置
            # 并更新当前root的右子树为包含目标val的新右子树
            root.right = self.insertIntoBST(root.right, val)

        # 返回更新后的以当前root为根节点的新树
        return root

450. 删除二叉搜索树中的节点

首先寻找需要删除的节点

如果找到的话,移动该子树

分情况讨论

  1. 没找到值
  2. 无左右子树
  3. 无左子树
  4. 无右子树
  5. 有左右子树 即中间节点

对第5种情况,改变时要注意是如何改变左右子树的

def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
    
    def remove(root):
        if not root:
            return
        if root.val < key:
            root.right = remove(root.right)
        elif root.val > key:
            root.left = remove(root.left)
        else:
            # if not root.left and not root.right:
            #     return
            if not root.left:
                return root.right
            if not root.right:
                return root.left
            # 中间节点
            # 相当于把target root和其左子树拿掉
            # 注意是定位到右子树
            # 放到最近的没有左子树的右子树左节点上
            cur = root.right
            while cur.left:
                cur = cur.left
            cur.left = root.left
            # 处理后相当于没有左子树的节点
            root = root.right
        return root
    
    return remove(root)

对比leetcode里的标答,删除后的树的结构还是有冗余的,可以再思考一下如何调整