我的个人微信公众号:Microstrong
微信公众号ID:MicrostrongAI
公众号介绍:Microstrong(小强)同学主要研究机器学习、深度学习、计算机视觉、智能对话系统相关内容,分享在学习过程中的读书笔记!期待您的关注,欢迎一起学习交流进步!
知乎专栏:https://zhuanlan.zhihu.com/Microstrong
个人博客:https://blog.csdn.net/program_developer
题目链接:
题目描述:
解题思路:
例如输入数组{5, 7, 6, 9, 11, 10,8 },则返回true,因为这个整数序列是图1二叉搜索树的后序遍历结果。如果输入的数组是{7, 4, 6,5 },由于没有哪棵二叉搜索树的后序遍历的结果是这个序列,因此返回false。
在后序遍历得到的序列中,最后一个数字是树的根结点的值。数组中前面的数字可以分为两部分:第一部分是左子树结点的值,它们都比根结点的值小:第二部分是右子树结点的值,它们都比根结点的值大。
以数组{5, 7, 6, 9, 11, 10, 8}为例,后序遍历结果的最后一个数字8就是根结点的值。在这个数组中,前3个数字5、7和6 都比8小,是值为8的结点的左子树结点:后3个数字9、11和 10 都比8大,是值为8的结点的右子树结点。
我们接下来用同样的方法确定与数组每一部分对应的子树的结构。这其实就是一个递归的过程。对于序列5、 7 、 6,最后一个数字6是左子树的根结点的值。 数字5比6小,是值为6的结点的左子结点,而7则是它的右子结点。同样,在序列9、 11、 10中,最后一个数字10是右子树的根结点, 数字9比10小, 是值为10的结点的左子结点, 而11则是它的右子结点。
我们再来分析另一个整数数组{7, 4 , 6,5 }。 后序遍历的最后一个数是根结点, 因此根结点的值是5。由于第一个数字7大于5,因此在对应的二叉搜索树中,根结点上是没有左子树的, 数字7、4和6都是右子树结点的值。但我们发现在右子树中有一个结点的值是4,比根结点的值5小,这违背了二叉搜索树的定义。因此不存在一棵二叉搜索树,它的后序遍历的结果是7、4、6、5。
找到了规律之后再写代码,就不是一件很困难的事情了。
已经AC的代码:
'''
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则输出Yes,否则输出No。假设输入的数组
的任意两个数字都互不相同。
'''
class Solution:
def VerifySquenceOfBST(self, sequence):
# 序列为空,返回False
if not sequence:
return False
# 获取序列的长度和二叉搜索树的根节点
length = len(sequence)
root = sequence[-1]
# 寻找二叉搜索树的左子树
for i in range(length):
if sequence[i] > root:
break
# 判断二叉树右子树中的每一个元素的值是否都比根节点的大
for j in range(i, length):
if sequence[j] < root:
return False
# 递归调用,分别查看二叉树的左右子树
left = right = True
if i > 0:
left = self.VerifySquenceOfBST(sequence[0:i])
if i < length - 1 and left:
right = self.VerifySquenceOfBST(sequence[i: -1])
# 当左右两个子树都返回True的时候,结果才是True
return left and right
if __name__ == "__main__":
sol = Solution()
# test 1
# seq = [5, 7, 6, 9, 11, 10, 8]
# test 2
seq = [4, 8, 6, 12, 16, 14, 10]
print(sol.VerifySquenceOfBST(seq))
Reference:
【1】《剑指offer》, 何海涛著。