7.6.3 (python)BST LeetCode题目 —— Delete Node in a BST & Recover Binary Search Tree

这一节再解析两道题,略有难度的。

450. Delete Node in a BST

Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.

Basically, the deletion can be divided into two stages:

  1. Search for a node to remove.
  2. If the node is found, delete the node.

Note: Time complexity should be O(height of tree).

题目解析

一道标准的基本功题目,前面对于AVL的结点的删除,没有详细解析。我们且看普通的BST的结点删除。

第一步,找到待删的结点;第二步,根据待删结点左右子树的情况,进行操作。

注意的是,当删除结点是根结点时,都要进行特殊处理,并返回新的根结点;不是的话,要记录待删结点的父节点(所以上一节的问题中,树的字段中保留了父结点,便于处理问题),并在删除结点后,将新的结点与这个父结点连接,返回值还是原来的根节点。

当删除结点既有左又有右子树时,确实问题比较复杂:1. 查找前继结点 2. 交接工作(左右子树交接) 3. 与删除结点的父亲相认

class Solution:
    def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
        p = root
        par = None  # 待删结点的父结点
        flag = 0  # par与待删结点的关系
        is_root = False  # 待删结点是否是根结点
        while p and key != p.val:
            par = p
            if key < p.val:
                flag = 0
                p = p.left
            else:
                flag = 1
                p = p.right
        if not p:
            return root
        if p == root:
            is_root = True        

        if not p.left and not p.right:
            if is_root:
                return None
            if flag:
                par.right = None
            else:
                par.left = None
        elif not p.left or not p.right:
            ch = p.left if p.left else p.right
            if is_root:
                return ch
            if flag:
                par.right = ch
            else:
                par.left = ch
        else:
            # 既有左子树也有右子树的
            q = p.left
            pre = p
            while q.right:
                pre = q
                q = q.right  # p左子树右下结点
            if pre != p:
                pre.right = q.left
                q.left = p.left
            q.right = p.right
            if is_root:
                return q
            if flag:
                par.right = q
            else:
                par.left = q
        return root

 

99. Recover Binary Search Tree

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

题目解析:

该题hard难度,但是实际上并没有太难的代码逻辑,关键是解题思路,BST中序遍历序列是递增,但是这两个错误的结点在中序遍历序列中一定是破坏了递增规律的。该方法跑起来蛮快的,就是一遍中序遍历,目标是找到两个结点对象:第一个是比后一个结点的值大的结点,即fir_node,第二个是比前一个结点的值小的结点,即sec_node。注意fir_node 的后一个结点是一定满足sec_node的,这个结点也真的可能是sec_node。最后我们把两个结点的值交换一下即可。该方法击败92%。

class Solution:
    def recoverTree(self, root: TreeNode) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        
        stack = []        
        pre_node = None        
        fir_node = None
        sec_node = None
        while root or stack:
            while root:
                stack.append(root)
                root = root.left
            root = stack.pop()
            if not fir_node:
                if pre_node:
                    if root.val < pre_node.val:
                        fir_node = pre_node
                        
            if fir_node:
                if root.val < pre_node.val:
                    sec_node = root
            
            pre_node = root
            root = root.right
        
        fir_node.val, sec_node.val = sec_node.val, fir_node.val

BST的内容先到这里,消化吸收一下。

下面继续是精彩的二叉树相关内容[捂脸]。。。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值