剑指offer33 二叉搜索树的后序遍历序列

方法一:递归分治 

    public boolean verifyPostorder(int[] postorder){
        return Solve(postorder,0,postorder.length-1);
    }

    public boolean Solve(int[] postorder,int i,int j){
        if(i>=j) return true;//表示此时子树结点<=1
        int m=i;
        while(postorder[m]<postorder[j]) m++;//找到左子树边界m-1
        int n=m;
        while(postorder[m]>postorder[j]) m++;//找到右子树边界m-1
        return m==j&&Solve(postorder,i,n-1)&&Solve(postorder,n,j-1);
    }

方法二:栈

思路:根据后序遍历的规律,倒序后序遍历,就可以得到root->right->left。观察倒序后的规律可得:

挨着的两个数如果arr[i]<arr[i+1],那么arr[i+1]一定是arr[i]的右子节点。

如果arr[i]>arr[i+1],那么arr[i+1]一定是arr[0]……arr[i]中某个节点的左子节点,并且这个值是大于arr[i+1]中最小的。

越往右子树遍历,值越大,如果一旦打破这一规律,就说明遍历到了左子树,为了确定这是谁的左子树,需要把右结点挨个遍历一遍,直到没有结点了或者遇到比左子树根结点小的右结点,遍历结束。这时就需要一个数据结构存储这些右结点,因此选择栈。而左子树的根结点就是最后弹出的那个结点,为了保存这个结点,设置变量prevElem。继续遍历后面的结点,后面的结点只有两类:左子树的子结点或其他结点的左子树子结点。但无论如何都应该比prevElem小,于是每个结点都和prevElem比较大小,并继续找左子树。

public boolean verifyPostorder(int[] postorder) {
        Deque<Integer> stack = new LinkedList<>();
        int pervElem = Integer.MAX_VALUE;
        for (int i = postorder.length - 1;i>=0;i--){
            if (postorder[i] > pervElem){
                return false;
            }
            while (!stack.isEmpty() && postorder[i] < stack.peek()){
                pervElem = stack.pop();
            }
            stack.push(postorder[i]);
        }
        return true;
    }

方法三:单调栈

public boolean verifyPostorder(int[] postorder){
        Stack<Integer> stack=new Stack<>();
        int root=Integer.MAX_VALUE;
        for(int i=postorder.length-1;i>=0;i--){
            if(postorder[i]>root) return false;
            while(!stack.isEmpty()&&stack.peek()>postorder[i]){
                root=stack.pop();
            }
            stack.push(postorder[i]);
        }
        return true;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值