题目
输入一个整数数组,判断该数组是不是某二叉搜索树的后续遍历结果,如果是则返回True,否则返回False。假设输入的数组的任意两个数字都互不相同。
例:
输入数组[5, 7, 6, 9, 11, 10, 8], 则返回True。因为这个整数序列是下树的后序遍历。
8
/ \
6 10
/ \ / \
5 7 9 11
如果输入的数组是[7, 4, 6, 5],则由于没有那棵二叉搜索树的后序遍历结构是这个序列,
因此返回False。
思路
- 和面试题7类似,理由后序遍历最后一个节点是根节点,左树小于根,右树大于根,逐步检验每个子树是否符合二叉搜索树规范。
- 时间复杂度:O(n^2),只有左树或右树的时候,每次都要检查T(n) = T(n-1) + O(n-1)
- 空间复杂度:O(n),只有左树或右树的时候
代码
思路1:时间复杂度:O(n^2), 空间复杂度:O(n)
def sequence_of_bst(postorder):
"""
:param postorder: LRD of binary search tree
:return: bool
"""
if len(postorder) <= 1:
return True
root = postorder[-1]
# right_child = postorder.filter(lambda x: x > root, postorder)
# left_child = postorder.filter(lambda x: x < root, postorder)
count = 0
for node in postorder[:-1]:
if node < root:
count += 1
else:
break
right_child = postorder[count:-1]
left_child = postorder[:count]
for node in right_child:
if node < root:
return False
if left_child:
left = sequence_of_bst(left_child)
else:
return True
if right_child:
right = sequence_of_bst(right_child)
else:
return True
return left and right
思考
- 能否不在每个节点检查子树的合规,而是先按照该序列构建二叉搜索树,然后再从底向上返回每个子树的最大和最小值,按照每个节点属于左树还是右树检查合规。可以这样的话,时间复杂度应该是O(n)的。
- # TODO: 具体代码待实践。