剑指 Offer 33. 二叉搜索树的后序遍历序列
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 中等
方法一:递归分治 时间复杂度O(n2) 空间复杂度O(n)
根据搜索二叉树的特性(root.left.val < root.val < root.right.val),以及后续遍历的特性(尾部元素为头节点),可将数组进行如下划分:
对于数组 [i , j],遍历找到首个比j大的元素,则该元素为右子树的头结点
- 区间[i , mid - 1]为左子树
- 区间[mid , j - 1]为右子树
- j为头结点
因为在找右子树的时候,已经证明左区间都比头结点的值小,故仅需要判断右区间与j的关系即可
递归的结束条件:区间长度为1 即 i >= j
def verifyPostorder(postorder): """ :type postorder: List[int] :rtype: bool """ def deal(i,j): if i >= j: return True l = 0 while postorder[l] < postorder[j]: l += 1 mid = l while postorder[l] > postorder[j]: l += 1 return l == j and deal(i,mid - 1) and deal(mid,j - 1) 这里没有判断值的关系,而是判断索引,即当 l != j时,说明右子树出现比头结点小的,不符合搜索二叉树特性 return deal(0,len(postorder)-1)
方法二:重建二叉树 时间复杂度O(n) 空间复杂度O(n)
后序遍历数组的倒序的顺序就变成了头右左的DFS,可以通过这一点重建二叉树,每放置一个节点就pop尾部元素,判断最后序列是否为空
def verifyPostorder(postorder): """ :type postorder: List[int] :rtype: bool """ def post(postorder,low,up): if postorder == []: return cur_val = postorder[-1] if not (low < cur_val < up): return postorder.pop() post(postorder,cur_val,up) post(postorder,low,cur_val) post(postorder,float('-inf'),float('inf')) return postorder == [] # 这里注意一点 ==是判断数据中的元素是否相同,而is是判断地址是否相同,即 [] == [] 输出True [] is [] 输出False,因为 [] 和 []是地址空间不同的两个列表

浙公网安备 33010602011771号