可以看出,**任何一个内部节点的取值,其左节点取值必定小于该节点取值,其右节点取值必定大于该节点取值。**接下来,我们看题:
剑指 Offer 33. 二叉搜索树的后序遍历序列
后序遍历,即左右根,那么序列的最后一个数据必定是根节点值,那么再结合是二叉搜索树,那么除根节点外的剩余数据,必定一部分是小于根节点值,另一部分是大于根节点值。
举个例子看的更清楚点:
{5, 7, 6, 9, 11, 10, 8} 为其后序遍历,这很简单。
8是根节点,5 7 6都是左子树且均小于8,9 11 10均为右子树且均大于8。
我们再看左子树5 7 6中,6是根节点,左子树5小于6,右子树7大于6。
右子树9 11 10同理。
以此类推。
除了判断整体数字上符合二叉搜索树的规则,其各个子树也必须要符合二叉搜索树的规则,所以使用递归来做是很方便的。
代码实现思路不难写,但是难点在于边界条件的考虑,我们在迅速写完主体逻辑代码后,就要考虑边界条件的情况,具体见代码注释:
class Solution(object):
def verifyPostorder(self, postorder):
"""
:type postorder: List[int]
:rtype: bool
"""
# 后序遍历 - 左右根
# 二叉搜索树,左值<根值<右值
if len(postorder) == 0:
return True
def helper(order):
if len(order) == 1:
return True
root = order[-1]
length = len(order)
for i in range(length):
if order[i] > root:
break
for j in range(i, length-1):
if order[j] < root:
return False
if i == 0: # 左子树为空
right = helper(order[:-1])
if right == False:
return False
elif i == length-1: # 右子树为空
left = helper(order[:-1])
if left == False:
return False
else:
left = helper(order[:i])
if left == False:
return False
right = helper(order[i:length-1])
if right == False:
return False
return True
return helper(postorder)
写递归的时候,尽量用这种helper的形式去写,更加便于理解,直接去调用本身的self函数虽然看似优美,但实则不易理解。