剑指offer_33_二叉搜索树的后序遍历序列【javascript】

73 阅读1分钟

题目

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

// 参考以下这颗二叉搜索树:
     5
    / \
   2   6
  / \
 1   3

示例 1:

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

示例 2:

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

提示:

  • 数组长度 <= 1000

题解

递归分治

/**
 * @param {number[]} postorder
 * @return {boolean}
 */
var verifyPostorder = function(postorder) {
    return recur(postorder, 0, postorder.length - 1);
};

var recur = (postorder, i, j) => {
    if (i >= j) return true;
    let p = i;
    while (postorder[p] < postorder[j]) { // postorder[j]根节点
        p++;
    }
    let m = p;
    while(postorder[p] > postorder[j]) {
        p++;
    }
    return p == j && recur(postorder, i, m - 1) && recur(postorder, m, j - 1);
}

复杂度分析

  • 时间复杂度:O(N^2)
  • 空间复杂度:O(N)

辅助单调栈

  1. 借助一个单调栈 stack 存储值递增的节点;
  2. 每当遇到值递减的节点 ri,则通过出栈来更新节点 ri的父节点 root ;
  3. 每轮判断 ri 和 root 的值关系:
  • 若 ri > root 则说明不满足二叉搜索树定义,直接返回 false 。
  • 若 ri < root 则说明满足二叉搜索树定义,则继续遍历。
/**
 * @param {number[]} postorder
 * @return {boolean}
 */
var verifyPostorder = function(postorder) {
    const stack = [];
    let root = Number.MAX_VALUE;
    for (let i = postorder.length - 1; i >=0; i--) {
        if (postorder[i] > root) return false;
        while (stack.length && stack[stack.length - 1] > postorder[i]) {
            root = stack.pop();
        }
        stack.push(postorder[i]);
    }
    return true;
};

复杂度分析

  • 时间复杂度:O(N)
  • 空间复杂度:O(N)

引用

  • 剑指offer书籍
  • 力扣题解