题目描述
// 33. 二叉搜索树的后序遍历序列
// 力扣
// 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。
// 如果是则返回 true,否则返回 false。假设输入的数组的任意两个数
// 字都互不相同。
// 牛客
// 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
// 如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互
// 不相同。
题解
// 首先关键抓手是 后序遍历 和 二叉搜索树(BST)
// 后序遍历的特点是取值会先取根节点的左树,然后取根节点的右树,最后才取根节点
// 而BST特点是左树结点值比根节点值小,根节点值又比右树结点值小,位置越靠左的越小
// 因此根据后序遍历的左右树先后顺序,和左右树大小问题,找到根节点之后就可以找
// 把左树元素和右树元素分离。分离之后继续找左子树右子树根节点,再把左子树右子树
// 各自的左右子树元素分离,以此循环下去。能够分离出来的就满足条件,
// 不能够分离出来的就返回false
// 力扣
// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:36.1 MB, 在所有 Java 提交中击败了23.01%的用户
class Solution {
public boolean verifyPostorder(int[] postorder) {
if (postorder.length == 0)
return false;
int head = 0;
int end = postorder.length - 1;
return recur(postorder, head, end);
}
private boolean recur(int[] postorder, int head, int end) {
if (head >= end) // 若head大于end或相等,遍历完成,返回true
return true;
int index = head; // 索引index用于从head到end遍历所有元素
// 若是后序遍历,postorder[end]必为根节点
// 根节点的左子树判断,若是BST,左子树元素必小于根节点postorder[end]
while (postorder[index] < postorder[end])
index++;
int mid = index; // 左子树
// 与左子树同理
while (postorder[index] > postorder[end])
index++;
// 若index能到达end(不满足条件时,index走不完postorder)
// 在左子树元素序列中递归recur
// 再右子树元素序列中递归recur
return (index == end) && recur(postorder, head, mid - 1) && recur(postorder, mid, end - 1);
}
}
// 牛客
// 运行时间:10ms
// 占用内存:9648k
public class Solution {
public boolean VerifySquenceOfBST(int [] sequence) {
if (sequence.length == 0)
return false;
int head = 0;
int end = sequence.length - 1;
return recur(sequence, head, end);
}
private boolean recur(int[] sequence, int head, int end) {
if (head >= end)
return true;
int index = head;
while (sequence[index] < sequence[end])
index++;
int mid = index;
while (sequence[index] > sequence[end])
index++;
return (index == end) && recur(sequence, head, mid - 1) && recur(sequence, mid, end - 1);
}
}