二叉查找树(Binary Search Tree) ,(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
题目描述:
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
思路:
-
法1: 后序遍历:左-右-根,后序遍历序列的最后一个是根节点,前面的分别是左子树节点序列和右子树节点序列。根据二叉搜索本身的性质,左子树所有节点的值都小于根节点的值,右子树所有结点的值都大于根节点的值。因此,从头依次判断前半部分元素是否都小于突变后部分的元素,突变后部分的元素是否都大于根节点。
-
法2:由法1的叙述可知,根节点为 s e q u e n c e [ − 1 ] sequence[-1] sequence[−1],因此可以在 s e q u e n c e [ : − 1 ] sequence[:-1] sequence[:−1]中寻找第一个大于根节点的元素的索引,然后将其划分为left和right两部分。将两部分排序后比较 l e f t [ − 1 ] left[-1] left[−1]和 r i g h t [ 0 ] right[0] right[0]即可:
- 如果 l e f t [ − 1 ] < r i g h t [ 0 ] left[-1] < right[0] left[−1]<right[0],返回True
- 否则返回False
-
递归法:
- 确定根节点root;
- 遍历序列(除去root结点),找到第一个大于root的位置,则该位置左边为左子树,右边为右子树;
- 遍历右子树,若发现有小于root的值,则直接返回false;
- 分别判断左子树和右子树是否仍是二叉搜索树
AC代码
# -*- coding:utf-8 -*-
class Solution:
def VerifySquenceOfBST(self, sequence):
# write code here
if sequence == []:
return False
if len(sequence) == 1:
return True
root = sequence[-1]
left_right = sequence[:-2]
for i in range(len(left_right)):
if left_right[i] > root:
for n in left_right[i:]:
if n < root:
return False
return True
return True
最值比较法
# -*- coding:utf-8 -*-
class Solution:
def VerifySquenceOfBST(self, sequence):
# write code here
if sequence == []:
return False
if len(sequence) == 1:
return True
root = sequence[-1]
s = sequence[:-1]
index = -1
r = []
for i in range(len(s)):
if s[i] > root:
for n in s[i:]:
# 如果可能的右子树部分出现小于root的值,直接返回False
if root > n:
return False
r.append(i)
index = i
break
# 如果只有左子树,直接返回True
if r == []:
return True
left = sorted(sequence[:index])
right = sorted(sequence[index:-1])
if left == [] or right == []:
return True
if left[-1] < right[0]:
return True
else:
return False
递归法:
class Solution:
def VerifySquenceOfBST(self, sequence):
# write code here
if sequence is None or len(sequence) == 0:
return True
# 首先找到根节点
root = sequence[-1]
n = len(sequence)
# 左子树结点值都小于根节点
i = 0
for i in range(n):
if sequence[i] > root:
break
# 右子树节点值都大于根节点
for j in range(i, n - 1):
if sequence[j] < root:
return False
# 判断左子树是不是二叉搜索树
left = True
if i > 0:
left = self.VerifySquenceOfBST(sequence[:i])
right = True
if i < n - 1:
right = self.VerifySquenceOfBST(sequence[i:-1])
return left and right