题目
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
代码实现
分治算法
class Solution {
public boolean verifyPostorder(int[] postorder) {
if (postorder == null || postorder.length == 1){
return true;
}
return recur(postorder,0,postorder.length-1);
}
public boolean recur(int[] postorder,int begin,int end){
if (begin >= end){
return true;
}
int index = begin;
//找到end节点的左子树,存边界为div,实际左子树是begin到div-1
while (postorder[index] < postorder[end]){
index++;
}
int div = index;
//index遍历结束一定是等于end,不然证明右子树中间有节点小于end节点的值,就不是二叉搜索树
while (postorder[index] > postorder[end]){
index++;
}
//从end节点的左子树和右子树分别遍历
return index == end && recur(postorder,begin,div-1) && recur(postorder,div,end-1);
}
}
单调栈
class Solution {
public boolean verifyPostorder(int[] postorder) {
Stack<Integer> stack = new Stack<>();
int parent = Integer.MAX_VALUE;
//注意for循环是倒叙遍历的
for (int i = postorder.length - 1; i >= 0; i--) {
int cur = postorder[i];
//当如果前节点小于栈顶元素,说明栈顶元素和当前值构成了倒叙,
//说明当前节点是前面某个节点的左子节点,我们要找到他的父节点
while (!stack.isEmpty() && stack.peek() > cur)
parent = stack.pop();
//只要遇到了某一个左子节点,才会执行上面的代码,才会更
//新parent的值,否则parent就是一个非常大的值,也就
//是说如果一直没有遇到左子节点,那么右子节点可以非常大
if (cur > parent)
return false;
//入栈
stack.add(cur);
}
return true;
}
}