33:二叉搜索树的后序遍历序列(剑指offer第2版Python)

1、题目描述

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

33:二叉搜索树的后序遍历序列(剑指offer第2版Python)_第1张图片

2、代码详解

根据后续遍历的性质,尾元素必定是树的根,同时小于尾元素的值是左子树,大于尾元素的值为右子树,且序列前半部分均小于尾元素,后半部分均大于尾元素(如果同时存在左右子树的话),可以将序列划分左子树序列和右子树序列,然后递归比较是否每一段均满足此性质。

法一:推荐

# -*- coding:utf-8 -*-
class Solution:
    def VerifySquenceOfBST(self, sequence):
        if len(sequence) == 0:
            return False
        return self.check(sequence, 0, len(sequence)-1)
    def check(self, arr, start, end):
        if start >= end:
            return True
        root = arr[end]
        end = end - 1
        while end >= 0 and arr[end] > root:
            end -= 1
        # 向前查找第一个小于root的值,mid-1就是分割处
        mid = end + 1
        for i in range(start, mid):
            if arr[i] > root:
                return False
        # 递归验证左子树[start,mid-1],右子树[mid,end]
        return self.check(arr, start, mid-1) and self.check(arr, mid, end)

# 测试代码
array = [5, 7, 6, 9, 11, 10, 8]
array2 = [7, 4, 6, 5]
array3 = [1, 2, 3, 4, 5]
S = Solution()
print(S.VerifySquenceOfBST(array))
print(S.VerifySquenceOfBST(array2))
print(S.VerifySquenceOfBST(array3))

法二

# -*- coding:utf-8 -*-
class Solution:
    def VerifySquenceOfBST(self, sequence):
        if sequence == []:
            return False
        root = sequence[-1]
        length = len(sequence)

        index = 0
        # 二叉搜索树中左子树节点的值小于根节点的值
        '''
        下面这个for循环特别需要主要index=i必须写在if语句外面,
        否则就会发生当root结点前的所有元素小于root的时候, 正确判断应该为True,
        但是因为if语句没有进入, index = 0 ,
        在进入二叉搜索树的右子树结点大于根结点的for循环的时候, 因为sequence的数都小于root, 就会判断出错
        '''
        for i in range(length - 1):
            index = i
            if sequence[i] > root:
                break

        # 二叉搜索树中右子树节点的值大于根节点的值
        '''
        这个循环中范围起始点必须是index+1, 不能为index
        因为当root结点前的所有元素小于root的时候,index=length-2,
        此时sequence[index]root, 所以从后面一个开始盘算右子树结点是否大于root, 也不会影响结果
        '''
        for j in range(index+1, length-1):
            if sequence[j] < root:
                return False

        # 递归验证
        # 判断左子树是不是二叉搜索树
        left = True
        if index > 0:
            left = self.VerifySquenceOfBST(sequence[:index])
        # 判断右子树是不是二叉搜索树
        right = True
        if index < length - 1:
            right = self.VerifySquenceOfBST(sequence[index:length-1])

        return left and right
# 测试代码
array = [5, 7, 6, 9, 11, 10, 8]
array2 = [7, 4, 6, 5]
array3 = [1, 2, 3, 4, 5]
S = Solution()
print(S.VerifySquenceOfBST(array))
print(S.VerifySquenceOfBST(array2))
print(S.VerifySquenceOfBST(array3))

可以减少递归深度的办法:某段的元素个数如果<=3,则返回True;某整段的最小元素不小于尾元素或者整段的最大元素不大于尾元素,说明仅有左子树或者右子树,返回True。

改进版待续

你可能感兴趣的:(牛客,剑指offer,二叉搜索树)