剑指 Offer 33. 二叉搜索树的后序遍历序列

剑指 Offer 33. 二叉搜索树的后序遍历序列

剑指 Offer 33. 二叉搜索树的后序遍历序列

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。

参考以下这颗二叉搜索树:

     5
    / \
   2   6
  / \
 1   3

示例 1:

输入: [1,6,3,2,5]
输出: false

示例 2:

输入: [1,3,2,6,5]
输出: true

提示:
    数组长度 <= 1000

思路

首先,二叉搜索树是一个,根的左子树上所有的节点值小于根的值,根的右子树上所有的节点值大于根的值。

由于是后序遍历,我们很容易知道,如果该数组是某一个二叉搜索树的结果,那么,数组最后一个元素一定是根节点

数组中,从左到右遍历,小于根节点的值,都是根的左子树
数组中,除去已经遍历到的小于根的值,剩余的值必须大于根节点的值,如果发现里面有小于根节点的值,则说明该数组不是某个二叉搜索树的后序遍历结果。
然后,递归判断根的左子树,递归判断根的右子树,是不是二叉搜索树即可。

class Solution {
    public boolean verifyPostorder(int[] postorder) {
        //边界条件
        if (postorder == null || postorder.length == 0) return true;

        if (postorder.length == 1) return true;

        int root = postorder[postorder.length - 1];

        int leftSubTreeCount = 0;
        while (postorder[leftSubTreeCount] < root) {
            leftSubTreeCount++;
        }
        int[] leftArray = new int[leftSubTreeCount];
        for (int i = 0; i<leftArray.length; i++) {
            leftArray[i] = postorder[i];
        }

        int rightSubTreeCount = leftSubTreeCount;
        while (rightSubTreeCount < postorder.length - 1) {
            if (postorder[rightSubTreeCount] < root) {
                return false;
            }
            rightSubTreeCount++;
        }

        int[] rightArray = new int[rightSubTreeCount];
        for (int i = leftSubTreeCount; i<rightArray.length; i++) {
            rightArray[i] = postorder[i];
        }

        return verifyPostorder(leftArray) && verifyPostorder(rightArray);

    }
}

程序写出来了,但是效率并不高
在这里插入图片描述

优化

class Solution {
    public boolean verifyPostorder(int[] postorder) {
        //边界条件
        if (postorder == null || postorder.length == 0) return true;

        return verifyPostorder(postorder, 0, postorder.length - 1);
    }

    public static boolean verifyPostorder(int[] postorder, int left, int right) {
        if (left >= right) return true;

        int root = postorder[right];

        //数组里面,左子树的右边界
        int leftSubTreeRightIndex = left;
        while (postorder[leftSubTreeRightIndex] < root) {
            leftSubTreeRightIndex++;
        }

        //数组里面,右子树的右边界
        int rightSubTreeRightIndex = leftSubTreeRightIndex;

        for (int i = rightSubTreeRightIndex; i < right; i++) {
            if (postorder[i] < root) {
                return false;
            }
        }
        return verifyPostorder(postorder, left, leftSubTreeRightIndex - 1) && verifyPostorder(postorder, leftSubTreeRightIndex, right - 1);
    }
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值