class Solution {
public boolean verifyTreeOrder(int[] postorder) {
return recur(postorder,0,postorder.length-1);
}
Boolean recur(int[] postorder,int i ,int j){
if(i>=j)return true;
int p = i;
while(postorder[p]<postorder[j])p++;
int m = p;
while(postorder[p]>postorder[j])p++;
return p == j && recur(postorder,i,m-1) && recur(postorder,m,j-1);
}
}
class Solution {
boolean recur(int[] postorder, int i, int j) {
if(i >= j) return true;
int p = i;
while(postorder[p] < postorder[j]) p++;
int m = p;
while(postorder[p] > postorder[j]) p++;
return p == j && recur(postorder, i, m - 1) && recur(postorder, m, j - 1);
}
public boolean verifyTreeOrder(int[] postorder) {
return recur(postorder, 0, postorder.length - 1);
}
}
class Solution {
public boolean verifyTreeOrder(int[] postorder) {
int n = postorder.length;
return helper(postorder, 0, n - 1);
}
public boolean helper(int[] postorder, int left, int right) {
if (left >= right) {
return true;
}
int p = left;
while (postorder[p] < postorder[right])
p++;
int m = p;
while (postorder[p] > postorder[right])
p++;
return p == right && helper(postorder, left, m - 1) && helper(postorder, m, right - 1);
}
}
class Solution {
public boolean verifyTreeOrder(int[] postorder) {
if (postorder == null) {
return true;
}
return f(postorder, 0, postorder.length - 1);
}
public boolean f(int[] post, int l, int r) {
if (l >= r) {
return true;
}
// 最后一个元素是根节点
int head = post[r];
int i = 0;
// 根据左小右大,区分左子树
while (post[i] < head) {
i++;
}
// 看看右子树是不是都大于根节点
for (int k = i; k <= r; k++) {
if (post[k] < head) {
return false;
}
}
// 递归左右子树
return f(post, l, i - 1) && f(post, i, r - 1);
}
}
共以下 20 个回答
LCR 152. 验证二叉搜索树的后序遍历序列
后序的最后一个元素为根节点,以此为分界线,遍历当前数组范围,先找第一个大于根的元素,在其后的数需要判断是否都大于根,如果不满足则返回false,满足则递归左右子树。
二叉搜索树后序遍历得最后一个节点一定是根节点,根据二叉搜索树的性质,左子树的节点值一定小于根节点的值,右子树的节点值一定大于根节点的值,先找到根节点,再从左到右遍历数组,找到第一个大于根节点的值,确定左子树和右子树的范围,再检查左子树和右子树。
解题思路
1、后续遍历:最后一个输出的点是根节点
2、二叉搜索树:输出顺序一定是,(x<根节点)(根节点<y)(根节点)。根节点是左子树x的最大值,根节点是右子树y的最小值。左子树、右子树也满足二叉搜索树的性质。
可以取出根节点,从左到右遍历整个数组,找到一个大于根节点的元素A,那么(0,A-1)就是左子树,(A,尾节点-1)就是右子树。左子树和右子树也满足二叉搜索树的性质。
按照二叉搜索树的定义,递归分治
时间o(n^2)
空间o(n)
错误点注意:刚开始写
if(start > end) return false;,会有空树用例失败,空树默认return true:if(start > end) return true;跟第一题类似,递归
时间复杂度O(n^2)
空间复杂度O(n)
后续遍历根节点为最后一个节点,利用二叉搜索树特点,可以遍历数组比根节点小的点为左子树节点,比根节点大的为右子树节点,然后递归判断左右子树是否满足。
时间复杂度O(N^2),空间复杂度O(N)。
思路:看完视频之后写的,还是根据后序遍历的规则,以及二叉搜索树的规律来综合思考
找到根节点之后通过找到第一个不小于根节点的数,切分左右子树
然后从右子树中搜索是否有不符合二叉搜索树规则的值,左右逐层递归
class Solution { stack = new Stack<>();
public boolean verifyTreeOrder(int[] postorder) {
// 创建一个栈用于存储节点值
Stack
// 初始化根节点值为最大整数
int root = Integer.MAX_VALUE;
}
分割左右子树,后序遍历先找到根节点的值,然后遍历数组找到第一个大于根节点的数值作为分割点,这是左右子树的分割点,然后从分割点向后遍历,只要postorder[index]大于根节点的值就向后继续,最后相等之后跳出循环,若是最后判断index不等于end,说明右子树并不是全部大于根节点,不合法,再递归判断此节点的左右子树,最后三个条件一起,得出结果
on on
class Solution {
public boolean verifyTreeOrder(int[] postorder) {
// [ [小于n][大于n] n]
boolean flag = false;
for(int i = 0; i < postorder.length; i++){
for(int j = i-1; j >= 0; j–){
if(postorder[j] < postorder[i]){
flag = true;
}
if(flag && postorder[j] > postorder[i]){
return false;
}
}
flag = false;
}
return true;
}
}
思路:从当前节点往前遍历,遍历到比当前点小后记录flag,然后继续遍历,如果出现比当前点小的值则返回false;
时间:O(n2)
空间:O(1)
class Solution {
public boolean verifyTreeOrder(int[] postorder) {
if (postorder null || postorder.length 0) return true;
return verify(postorder,0,postorder.length-1);
}
}
思路:根据二叉搜索树的性质判断左右子树在
postorder上的区间,并依次递归的判断左右子树是否也满足二叉搜索树的后序遍历序列。时间复杂度:最坏情况是 O(n^2^),平均情况 O(nlogn)。
空间复杂度:O(n),递归调用栈空间。
思路: 首先根据搜索树性质 划分出 左右子树 依次递归判断 左右子树