剑指offer 33. 二叉搜索树的后序遍历序列
题目描述
解题思路
如果仅知道普通二叉树的后序遍历序列,则无法恢复原来的二叉树,因为无法确定左右子树的下标范围。
但这题是二叉搜索树,能够根据特殊性质确定出左右子树的下标范围。
另外,当 endOfLeft
和 index
递减时,需要注意下标越界问题,并且这里的左边界不是0,而是begin。
class Solution {
public boolean verifyPostorder(int[] postorder) {
if (postorder.length == 0) return true;
return verifyPostorder(postorder, 0, postorder.length - 1);
}
//判断 postorder[begin...end] 是否是二叉搜索树的后序遍历结果
public boolean verifyPostorder(int[] postorder, int begin, int end) {
// base case
if (begin >= end) return true;
int endOfLeft = end; //左子树的结束索引
//左子树结束索引对应的元素是第一个比 postorder[end] 小的元素
while (endOfLeft >= begin && postorder[endOfLeft] >= postorder[end]) endOfLeft--;
//由于上面 while 遍历时,已经确保了右子树的所有元素都大于 postorder[end],所以要继续判断左子树的正确性
int index = endOfLeft;
while (index >= begin && postorder[index] < postorder[end]) index--;
//首先要保证左子树的正确性,然后继续遍历左子树和右子树
return (index + 1 == begin) && verifyPostorder(postorder, begin, endOfLeft)
&& verifyPostorder(postorder, endOfLeft + 1, end - 1);
}
}