美文网首页
二叉搜索树的后序遍历序列 2022-03-01 周二

二叉搜索树的后序遍历序列 2022-03-01 周二

作者: 勇往直前888 | 来源:发表于2022-03-01 17:08 被阅读0次

题目

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

学习

JS解法

Java解法

分析

  • 后序遍历定义: [ 左子树 | 右子树 | 根节点 ] ,即遍历顺序为 “左、右、根” 。

  • 二叉搜索树定义: 左子树中所有节点的值 << 根节点的值;右子树中所有节点的值 >> 根节点的值;其左、右子树也分别为二叉搜索树。

后续遍历
  • 二叉搜索树后续遍历用数组表示,最后一个元素就是root
    剩下的,以root为标准,分为左子树(都 < root)和右子树(都 > root)

  • 递归:左子树和右子树仍然是二叉搜索树。

思路

  • JS中Array的pop就是取出最后一个元素,也就是root;同时root也取出了,只剩下左右子树了。

  • 以root为标准,从0号元素开始比较,小于root的都是属于左子树,剩下的事又子树。JS中Array的slice方法可以分开左右子树。

  • 左子树已经检查过,剩下的右子树遍历检查一下,要求都大于root

  • 递归:将上面的过程继续在左右子树重复做

  • 退出条件:数组元素个数少于3个;

比如两个元素,那么第2个元素就是root;
第1个元素如果< root,那么就可以认为是左子树;
第1个元素如果> root,那么就可以认为是右子树;

JS代码

/**
 * @param {number[]} postorder
 * @return {boolean}
 */
var verifyPostorder = function(postorder) {
    // 退出条件,元素个数不足3个,必然符合条件
    if (postorder.length < 3) {
        return true;
    }

    // 取出判断标准root,也就是最后一个元素
    let root = postorder.pop();

    // 找出左右子树的分界点; i的左边(不包括i)是左子树;i的右边(包括i)是右子树
    let i = 0;
    while (postorder[i] < root) {
        i++;
    }

    // 以i为界限(i属于右子树),分为左右子树
    let leftTree = postorder.slice(0, i); // 刚好,i不包括
    let rightTree = postorder.slice(i); // 刚好,i包括在内

    // 左子树不用查,检查右子树
    let rightResult = rightTree.every(
        (item) => {
            return item > root;
        }
    );
    
    // 如果右子树不对,直接返回FALSE,剩下的就不用查了;
    if (!rightResult) {
        return false;
    }

    // 继续查左右子树,并且要求两者都要正确
    return (verifyPostorder(leftTree) && verifyPostorder(rightTree));
};

备注

JS不查类型,用起来很灵活;但是同样地,也很容易犯错。比如 if (!rightResult) 这个地方错误写成了 if (!rightTree) ,就很难查出问题。(很多用例可以过)

错误结果 错误代码之处

相关文章

网友评论

      本文标题:二叉搜索树的后序遍历序列 2022-03-01 周二

      本文链接:https://www.haomeiwen.com/subject/fjzdrrtx.html