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

二叉搜索树的后序遍历序列

题目描述

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

示例1

输入

[4,8,6,12,16,14,10]

返回值

true

分析

方案一:递归分治

/**
时间复杂度 O(N^2)
每次调用 recur(i,j) 减去一个根节点,因此递归占用 O(N) 最差情况下(即当树退化为链表),每轮递归都需遍历树所有节点,占用 O(N)。
空间复杂度 O(N) : 最差情况下(即当树退化为链表),递归深度将达到 N 。
**/
class Solution
{
public:
    bool recur(vector<int> postorder, int i, int j)
    {
        // 当i>=j,说明此子树节点数量<=1,无需判断正确性,直接返回true
        if (i >= j)
            return true;
        int p = i;
        //左子树区间[i,m-1]
        while (postorder[p] < postorder[j])
            p++;
        //划分左右子树,第一个大于根节点的节点索引记为m
        int m = p;
        // 右子树区间[m,j-1]
        while (postorder[p] > postorder[j])
            p++;
        // p == j来判断是否为二叉搜索树
        return p == j && recur(postorder, i, m - 1) && recur(postorder, m, j - 1);
    }
    bool verifyPostorder(vector<int> postorder)
    {
        return recur(postorder, 0, postorder.size() - 1);
    }
};

方案二:辅助单调栈

/**
时间复杂度 O(N) : 遍历 postorder 所有节点,各节点均入栈 / 出栈一次,使用 O(N) 时间。
空间复杂度 O(N) : 最差情况下,单调栈 stack 存储所有节点,使用 O(N) 额外空间。
**/
class Solution
{
public:
    bool VerifySquenceOfBST(vector<int> sequence)
    {
        stack<int> st;
        int root = INT_MAX;
        for (int i = sequence.size() - 1; i >= 0; i--)
        {
            // 若 ri > root,说明此后序遍历序列不满足二叉搜索树定义,直接返回 false;
            if (sequence[i] > root)
                return false;
            // 当栈不为空 且 ri < stack.top()时,循环执行出栈,并将出栈节点赋给 root
            while (!st.empty() && st.top() > sequence[i])
            {
                root = st.top();
                st.pop();
            }
            // 将当前节点 ri入栈
            st.push(sequence[i]);
        }
        // 若遍历完成,则说明后序遍历满足二叉搜索树定义,返回 true
        return true;
    }
};
posted @ 2020-12-22 23:23  RiverCold  阅读(36)  评论(0编辑  收藏  举报