描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回 true ,否则返回 false 。假设输入的数组的任意两个数字都互不相同。
数据范围: 节点数量 0≤n≤1000 ,节点上的值满足 1≤val≤10^5 ,保证节点上的值各不相同
要求:空间复杂度 O(n) ,时间时间复杂度 O(n^2)
提示:
1.二叉搜索树是指父亲节点大于左子树中的全部节点,但是小于右子树中的全部节点的树。
2.该题我们约定空树不是二叉搜索树
3.后序遍历是指按照 “左子树-右子树-根节点” 的顺序遍历
4.参考下面的二叉搜索树,示例 1
示例1
输入:
[1,3,2]
返回值:
true
说明:
是上图的后序遍历 ,返回true
示例2
输入:
[3,1,2]
返回值:
false
说明:
不属于上图的后序遍历,从另外的二叉搜索树也不能后序遍历出该序列 ,因为最后的2一定是根节点,前面一定是孩子节点,可能是左孩子,右孩子,根节点,也可能是全左孩子,根节点,也可能是全右孩子,根节点,但是[3,1,2]的组合都不能满足这些情况,故返回false
示例3
输入:
[5,7,6,9,11,10,8]
返回值:
true
初看此题 没有什么好思路 只有暴力:
根据 后序+中序=》还原BST
再对BST进行后续遍历 与输入的后续比较 若一致 返回true 否则返回false后续数组:int[] post; 中序数组:int[] vin;
结果写着写着发现,当不是BST的后序序列时会抛数组越界异常,也就是vin中找不到post最后一个元素(应该是根)
这时有了启发,一旦出现vin中找不到根,说明肯定不是BST,此时就可以得到最终结果了!!
我的代码:
import java.util.Arrays;
public class Solution {
boolean flag=true;
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence.length==0) return false;
int [] vin =Arrays.copyOf(sequence,sequence.length);
Arrays.sort(vin);
reConstructBinaryTree(sequence,vin);//出一次错就flag==false
return flag;
}
//能还原就是 不能还原就不是
public void reConstructBinaryTree(int [] post,int [] vin) {
if(post.length==0||flag==false) return;
TreeNode root=new TreeNode(post[post.length-1]);//后序最后一个是根
int k=0;
for(k=0;k<vin.length&&vin[k]!=post[post.length-1];k++);
if(k==vin.length) {flag=false; return;}//找不到,数组越界了 直接得到false结果
if(k>0) reConstructBinaryTree(Arrays.copyOfRange(post,0,k),Arrays.copyOfRange(vin,0,k));//递归创建左右子树
if(post.length-k-1>0) reConstructBinaryTree(Arrays.copyOfRange(post,k,post.length-1),Arrays.copyOfRange(vin,k+1,vin.length));
}
}
换种思路,抛却还原二叉树的想法,二分找矛盾
待做.....
方法二:栈
二叉树的中序遍历和后序遍历对应着一种栈的压入、弹出序列
中序看做是一种入栈序列 则后序必然是其中一种出栈序列
后期 结合 JZ31题一起做吧
O(n^2的话就好做了 升序入栈 则后面比我小的一定严格降序 很好找矛盾)