zoukankan      html  css  js  c++  java
  • 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这题中有应用

  • 相关阅读:
    echarts饼图标题居中以及调整主副标题的间距
    同一页面多个echarts自适应窗口
    element添加人员判断不能重复添加(复选框禁用)
    element根据不同的tab页签进行检索
    vue+element 表格单元格内添加/编辑
    Pycharm 中 Material Theme UI等插件
    Redis 知识记录
    李宏毅老师hw1 linear regression模型改进
    李宏毅老师regression部分全部
    李宏毅老师hw1 linear regression模型
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5660384.html
Copyright © 2011-2022 走看看