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 itres
. However, we don't know if there is anymore node onroot
's left that is larger thanp.val
. So we move root to its left and check again. -
root.val <= p.val
. In this case,root
cannot bep
's inorder successor, neither canroot
's left child. So we only need to considerroot
'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 阅读(388) 评论(0) 编辑 收藏 举报