剑指 Offer 33. 二叉搜索树的后序遍历序列
题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
递归:
class Solution:
def verifyPostorder(self, postorder: List[int]) -> bool:
def istrue(begin,end):
if begin >= end:
return True
root = postorder[end]
i = begin
while root > postorder[i]:
i += 1
j = i
while root < postorder[j]:
j += 1
return j == end and istrue(begin, i - 1) and istrue(i, end - 1)
return istrue(0, len(postorder) - 1)
从 i 停下位置开始往上递增 j 防止极端情况倒数第二个比倒一大
辅助栈方法:
class Solution:
def verifyPostorder(self, postorder: List[int]) -> bool:
stack, root = [], float("+inf")
for i in range(len(postorder) - 1, -1, -1):
if postorder[i] > root://如果接受了大于当前root的值,返回False
return False
while stack and stack[-1] > postorder[i]:
root = stack.pop()//找到那个可以接上左子树的根节点,以后的值不能超过他了
stack.append(postorder[i])
return True
思路:
每次值的变化都在从右子树到左子树的时候发生。说明当前值需要接在某个节点左边
【【【左 右 根】 【左 右 根】 根】 【【左 右 根】 【左 右 根】根】 根】
倒序遍历:根 -> 右 -> 左 每次发现值变小时,说明进入了当前最近根下的左子树,将右子树和根出栈找到当前根,进行判断。
根的遍历顺序:右 -》 根 -》 左
因为遇到左子树就会出栈当前根,每次先遍历出栈右子树的根,再遍历出栈中间的根,最后出栈左子树的根。
每次会残存左子树在栈里,在遍历左子树所在的更大右子树的兄弟左子树时,残存左子树一定比当前值大而出栈。