【剑指offer】23.二叉搜索树的后序遍历序列[by Python]

题目描述:

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

解题方法

我们都知道BST的中序遍历是有序的,后序遍历时,最后的节点是根节点。那么可以先找根节点,然后利用根节点的值,把数组分成两部分,前部分都比根节点小是左子树,后部分都比根节点大是右子树。然后再分别遍历左右子树即可。我做这个题的时候利用从左遍历找到第一个比根节点的大的位置划分左右节点,这样保证了左边部分都比根节点小,不能保证右边部分都比根节点大,所以对右边的部分进行了验证。另外题目中有个坑,题目认为,空树不是BST……所以新定义了函数进行递归,否则会更简单点。

# -*- coding:utf-8 -*-
class Solution:
    def VerifySquenceOfBST(self, nums):
        if not nums: return False
        return self.verifyBST(nums)

    def verifyBST(self, nums):
        if not nums: return True
        root = nums.pop()
        index = self.findIndex(nums, root)
        if self.verifyRight(nums[index:], root):
            left = nums[:index]
            right = nums[index:]
            return self.verifyBST(left) and self.verifyBST(right)
        return False

    def verifyRight(self, nums, target):
        if not nums: return True
        return min(nums) > target

    def findIndex(self, nums, target):
        for i, num in enumerate(nums):
            if num > target:
                return i
        return len(nums)
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

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

思路:二叉搜索树是对一个有序数组进行二分查找形成的搜索树,它指一棵空树或者具有下列性质的二叉树:

  • 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  • 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  • 任意节点的左、右子树也分别为二叉查找树;

以下图二叉树为例,我们都知道对二叉搜索树进行中序遍历可以还原为一个有序数组,而图中二叉树后序遍历结果为[3,2,4,6,8,75]。接下来分析一下这个数组的规律。首先按照后序遍历的性质,数组的最后一个元素即是整个二叉树的根结点。另外按照搜索二叉树的前两条性质,左子树均小于根(红色部分),右子树均大于根(蓝色部分)。左右子树部分同样符合整个规律,所以我们可以递归实现数组的判断。



# -*- coding:utf-8 -*-
class Solution:
    def VerifySquenceOfBST(self, sequence):
        # write code here
        if len(sequence) == 0:
            return False
        else:
            root = sequence[-1]
            del sequence[-1]
            lefttree = []
            righttree =[]
            # 左子树和右子树分界
            splitindex = -1
            for i in range(len(sequence)):
                # 值小于根结点的归为左子树
                if sequence[i] < root:
                    lefttree.append(sequence[i])
                    splitindex = i
                else:
                    break
            for i in range(splitindex+1, len(sequence)):
                # 若右子树部分有小于根结点的值,说明不是二叉搜索树
                if sequence[i] > root:
                    righttree.append(sequence[i])
                else:
                    return False
            if len(lefttree) <= 1:
                left = True
            else:
                # 递归判断左子树
                left = self.VerifySquenceOfBST(lefttree)
            if len(righttree) <= 1:
                right = True
            else:
                right = self.VerifySquenceOfBST(righttree)
            return left and right
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
      <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-e44c3c0e64.css" rel="stylesheet">
              </div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值