1. 题目
2. 思路
(1) 递归
- 后序遍历的结果是[左子树][右子树][根结点],二叉搜索树的性质是左子树的所有结点均小于根结点,右子树的所有结点均大于根结点。
- 因此,对于任意一个后序遍历,可以先从左往右找到第一个大于根结点的结点,此结点之前就是左子树,之后就是右子树。
- 由于已经确定左子树中的所有结点均大于根结点,因此遍历右子树,若找到小于根结点的结点,则此后序遍历不成立。
(2) 单调栈
- 维护一个单调递减栈和根结点的值,存储根结点的右子树,若某个结点的值直接大于根结点,则返回false。
3. 代码
import java.util.Deque;
import java.util.LinkedList;
public class Test {
public static void main(String[] args) {
}
}
class Solution {
public boolean verifyPostorder(int[] postorder) {
if (postorder.length == 0) {
return true;
}
return verifyPostorder(postorder, 0, postorder.length - 1);
}
private boolean verifyPostorder(int[] postorder, int left, int right) {
if (left >= right) {
return true;
}
int mid = left;
while (mid < right) {
if (postorder[mid] > postorder[right]) {
break;
}
mid++;
}
for (int i = mid + 1; i < right; i++) {
if (postorder[i] < postorder[right]) {
return false;
}
}
return verifyPostorder(postorder, left, mid - 1) && verifyPostorder(postorder, mid, right - 1);
}
}
class Solution1 {
public boolean verifyPostorder(int[] postorder) {
Deque<Integer> stack = new LinkedList<>();
int root = Integer.MAX_VALUE;
for (int i = postorder.length - 1; i >= 0; i--) {
if (postorder[i] > root) {
return false;
}
while (!stack.isEmpty() && postorder[i] < stack.peek()) {
root = stack.pop();
}
stack.push(postorder[i]);
}
return true;
}
}