剑指 Offer 33. 二叉搜索树的后序遍历序列
难度中等253
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true
,否则返回 false
。假设输入的数组的任意两个数字都互不相同。
参考以下这颗二叉搜索树:
5
/ \
2 6
/ \
1 3
示例 1:
输入: [1,6,3,2,5]
输出: false
示例 2:
输入: [1,3,2,6,5]
输出: true
提示:
数组长度 <= 1000
思路:
1.单调栈,
2.递归分治
3.中序后序判断树
Code1:单调栈 (O(N),O(N))
class Solution {
public boolean verifyPostorder(int[] postorder) {
Deque<Integer>stack=new LinkedList<Integer>();
int root=Integer.MAX_VALUE;
//O(n) O(n)
//逆序 根右左 先增后减 所以可以用单调栈
for(int i=postorder.length-1;i>=0;i--)
{
if(postorder[i]>root) return false;
while(!stack.isEmpty()&&stack.peek()>postorder
[i])//开始递减的时候要更新root;
{
root=stack.pop();
}
stack.push(postorder[i]);
}
return true;
}
}
Code2:递归分治(O(N^2),O(N))
class Solution {
public boolean verifyPostorder(int[] postorder) {
return recur(postorder, 0, postorder.length - 1);
}
//根据后序遍历的特点 分治来算 O(N^2) O(N)
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);
}
}
Code3:中序后序判断树(O(N^2),O(N))
class Solution {
//中序遍历+后序遍历 确定树 O(n^2) O(n)
HashMap<Integer,Integer>map;
public boolean isOk(int mid[],int post[],int s1,int e1,int s2,int e2)
{
int rootId=map.get(post[e2]);
for(int i=s2;i<s2+rootId-s1;i++)
{
if(post[i]>post[e2])
return false;
}
for(int i=s2+rootId-s1;i<e2;i++)
{
if(post[i]<post[e2])
return false;
}
if(rootId-1<=s1&&e1>rootId+1)//左子树ok 遍历右子树
return isOk(mid,post,rootId+1,e1,s2+rootId-s1,e2-1);
if(rootId-1>s1&&e1<=rootId+1)//右子树ok 遍历左子树
return isOk(mid,post,s1,rootId-1,s2,s2+rootId-1-s1);
if(rootId-1<=s1&&e1<=rootId+1)//左右子树都ok
return true;
return isOk(mid,post,s1,rootId-1,s2,s2+rootId-1-s1)&&isOk(mid,post,rootId+1,e1,s2+rootId-s1,e2-1);
}
public boolean verifyPostorder(int[] postorder) {
int n=postorder.length;
if(n<2) return true;
int midorder[]=new int[n];
for(int i=0;i<n;i++)
midorder[i]=postorder[i];
Arrays.sort(midorder);
map=new HashMap<>();
for(int i=0;i<n;i++)
map.put(midorder[i],i);
return isOk(midorder,postorder,0,n-1,0,n-1);
}
}