• Inorder Successor in BST


    Given a binary search tree and a node in it, find the in-order successor of that node in the BST.

    Note: If the given node has no in-order successor in the tree, return null.

    要求返回给定二叉搜索树BST的中的一个节点.要求求该节点的后继节点.

    BST的特点是: 左节点的值小于等于父节点, 右节点的值大于等于父节点.所以可以利用这个属性来进行搜索.具体方案和算法导论给出的在BST中找特定节点的流程是一样的.

    但是需要注意的是因为求的是后续节点.我们实际要求的是比给定节点值大的最小节点.所以每个比给定节点值大的点都可能是.但是我们需要不断缩小搜索范围. 使找到的下一个比节点值大的点的值比之前的candidate要小.

    给出这种解法的代码,平均时间复杂度为O(h), h为高度.空间复杂度为O(1).

    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def inorderSuccessor(self, root, p):
            """
            :type root: TreeNode
            :type p: TreeNode
            :rtype: TreeNode
            """
            if not root or not p:
                return None
            cur = root
            succ = None
            while cur:
                if p.val < cur.val:
                    succ = cur  #可能的后继
                    cur = cur.left
                else:
                    cur = cur.right
            return succ

    给出一个leetcode上的解释:

    The idea is to compare root's value with p's value if root is not null, and consider the following two cases:

    • root.val > p.val. In this case, root can be a possible answer, so we store the root node first and call it res. However, we don't know if there is anymore node on root's left that is larger than p.val. So we move root to its left and check again.

    • root.val <= p.val. In this case, root cannot be p's inorder successor, neither can root's left child. So we only need to consider root's right child, thus we move root to its right and check again.

    We continuously move root until exhausted. To this point, we only need to return the res in case 1.

    其实本质这种策略是抛弃不可能有candidate的子树,但是保存可能是最终结果的candidate.因为每次在p.val < cur.val的时候,我们继续在cur的左子树查找,所以找到的candidate肯定比cur小. succ是不断缩小的.

    以上解法可以做剪枝,也就是在给定的p节点有右子数时,后续节点实际是该右子树的最左节点,代码如下:

    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        """
        @param root <TreeNode>: The root of the BST.
        @param p <TreeNode>: You need find the successor node of p.
        @return <TreeNode>: Successor of p.
        """
        def inorderSuccessor(self, root, p):
            if not root:
                return None
            succesor = None
            if  p and p.right:
                succesor = p.right
                while succesor.left:
                    succesor = succesor.left
                return succesor
            while root:
                if root.val > p.val:
                    succesor = root
                    root = root.left
                elif root.val < p.val:
                    root = root.right
                else:
                    break
            return succesor

    另外就是基于中序遍历的解法,这种不需要限定在BST上,所以更general.具体是在查找到节点后,查找后续处理的那个节点.稍微修改下非递归中序遍历的代码就可以.时间复杂度O(n)(因为遍历了,平均空间复杂度为O(logn),栈,可以验证),

    代码如下:

    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def inorderSuccessor(self, root, p):
            """
            :type root: TreeNode
            :type p: TreeNode
            :rtype: TreeNode
            """
            if not root or not p:
                return None
            cur = root
            stack = []
            flag = False
            while cur or stack:
                if cur:
                    stack.append(cur)
                    cur = cur.left
                else:
                    cur = stack.pop()
                    if flag:
                        return cur 
                    if cur == p:
                        flag = True 
                    cur = cur.right
            return None

    后面这种解法可以持续不断的进行下去.查找第一个后继,第二个后继,等等,所以在Binary Search Tree Iterator这题中有应用

  • 相关阅读:
    时序图
    用例图
    欢迎界面(闪屏)
    WBS
    闲来听书
    软件团队的模式
    结对编程
    在个人项目中,找bug,审核代码.
    时序图
    部分功能的实现
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5660384.html
Copyright © 2020-2023  润新知