给你一个二叉搜索树和其中的某一个结点,请你找出该结点在树中顺序后继的节点。
结点 p 的后继是值比 p.val 大的结点中键值最小的结点。
示例 1:
输入: root = [2,1,3], p = 1
输出: 2
解析: 这里 1 的顺序后继是 2。请注意 p 和返回值都应是 TreeNode 类型。
示例 2:
输入: root = [5,3,6,2,4,null,null,1], p = 6
输出: null
解析: 因为给出的结点没有顺序后继,所以答案就返回 null 了。
注意:
假如给出的结点在该树中没有顺序后继的话,请返回 null
我们保证树中每个结点的值是唯一的
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/inorder-successor-in-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
二叉搜索树特点:中序遍历为升序数组。
所以通过中序遍历,可以知道比p.val大的最小节点的值,
因为返回的是TreeNode,所以光知道值还不够,
在中序遍历的过程中,还要利用哈希表,记录下树的每个节点的值和这个节点的映射,key是值, val是这个节点。
# 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:
return None
mapping = dict()
def inorder(node):
if not node:
return []
mapping[node.val] = node
return inorder(node.left) + [node.val] + inorder(node.right)
Inorder = inorder(root)
# print Inorder
for i, val in enumerate(Inorder):
if val == p.val:
return mapping[Inorder[i + 1]] if i != len(Inorder) - 1 else None
优化一下:
AC之后发现实际上并没有必要开哈希表,直接在中序遍历的结果里存Node而不是Node.val即可。
class Solution(object):
def inorderSuccessor(self, root, p):
"""
:type root: TreeNode
:type p: TreeNode
:rtype: TreeNode
"""
if not root:
return None
def inorder(node):
if not node:
return []
return inorder(node.left) + [node] + inorder(node.right)
Inorder = inorder(root)
for i, node in enumerate(Inorder):
if node.val == p.val:
return Inorder[i + 1] if i != len(Inorder) - 1 else None
第二种思路:
其实可以先比较一下 root.val 和 p.val 的大小关系,
1. 如果 root.val > p.val,那么可以肯定,解必定存在,如果p是root的左子树中最大的元素,那么解就是root;否则,应该在root.left 里找解。
2. 如果root.val <= p.val,那么不能确定解存不存在,只能在root.right里找解。
class Solution(object):
def inorderSuccessor(self, root, p):
"""
:type root: TreeNode
:type p: TreeNode
:rtype: TreeNode
"""
if root:
if root.val > p.val: # p is in the left subtree of root
return self.inorderSuccessor(root.left, p) or root
return self.inorderSuccessor(root.right, p)