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

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

题目描述

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

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

     5
    / \
   2   6
  / \
 1   3
示例 1:

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

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

思路

二叉搜索树特点:左子树比当前值小,右子树比当前值大;即左子树的全部结点都比当前值小,右子树的所有结点都比当前值大
后序遍历(LRD): [ 左 子 树 \color{red}{[左子树} [| 右 子 树 \color{red} {右子树} | 根 节 点 ] \color{red}{根节点]} ]
递归:
1:终止条件:if(start >= end) return true
2:根据当前范围的根节点,划分左右子树,左子树的值都比当前根节点要小,右子树的值都比当前根节点要大
3:因为第2步划分时验证了左子树,那么接下来根据划分的右子树验证是否都比根节点要大
4:递归判断左右子树

代码
bool isPostorder(vector<int>& postorder, int start, int end){
		//递归终止条件
        if(start >= end) return true;
        //找到左子树和右子树的划分点
        int i = start;
        while(postorder[i] < postorder[end]){
            i++;
        }
        int bound = i;
        //遍历右子树,判断是否都比根节点大
        for(; i < end; i++){
            if(postorder[i] < postorder[end]) return false;
        }
        //递归遍历左右子树
        return isPostorder(postorder, start, bound-1) && isPostorder(postorder, bound, end-1);
    }
    bool verifyPostorder(vector<int>& postorder) {
        int n = postorder.size();
        if(n == 1) return true;
        if(n == 2) return postorder[0]>postorder[1];

        return isPostorder(postorder, 0, n-1);
    }
复杂度分析
时间复杂度: O ( N 2 ) O(N^2) O(N2)

当树退化成链表,每一次递归,都需要遍历树的所有结点,占用 O ( N ) O(N) O(N)

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

最差情况下(即当树退化为链表),递归深度将达到 N N N

你可能感兴趣的:(算法,#,剑指offer)