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这题中有应用

 

posted on 2016-07-11 15:22  Sheryl Wang  阅读(392)  评论(0编辑  收藏  举报

导航