zoukankan      html  css  js  c++  java
  • 剑指Offer_#33_二叉搜索树的后续遍历

    剑指Offer_#33_二叉搜索树的后续遍历

    Contents

    题目

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

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

         5
        / 
       2   6
      / 
     1   3

    示例 1:

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

    示例 2:

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

    提示:
    数组长度 <= 1000

    思路分析

    二叉搜索树(二叉查找树)

    二叉查找树(BST:Binary Search Tree)是一种特殊的二叉树,它改善了二叉树节点查找的效率。二叉查找树有以下性质:
    对于任意一个节点 n,

    • 其左子树(left subtree)下的每个后代节点(descendant node)的值都小于节点 n 的值;
    • 其右子树(right subtree)下的每个后代节点的值都大于节点 n 的值。

    所谓节点 n 的子树,可以将其看作是以节点 n 为根节点的树。子树的所有节点都是节点 n 的后代,而子树的根则是节点 n 本身。
    下图中展示了两个二叉树。二叉树(b)是一个二叉查找树(BST),它符合二叉查找树的性质规定。而二叉树(a),则不是二叉查找树。


    更加详细的部分,参考二叉查找树 - sangmado - 博客园

    思路

    • 后续遍历的顺序是左-右-根,即在每个子树的后续遍历序列当中,最后一个数字总是根节点的值,前面的一串数字,前半部分表示左子树,后半部分表示右子树。
    • 根据BST的定义,左子树的每个节点的值都小于根节点的值,右子树的每个节点的值都大于根节点的值。我们可以据此找到后序遍历序列当中,左右子树的分界点,即:找到第一个比根节点的值大的数字,这个数就是右子树的第一个节点,它的左边的数字都是表示左子树,右边的数字都是表示右子树。
    • BST的所有子树也都是BST。

    根据以上几条,我们可以考虑使用递归的写法,递归判断每个节点的子树是否是BST,直到叶节点。

    算法流程

    辅助变量startend表示要判断的子树在后续遍历序列中的范围。

    • 出口条件start >= end,说明这个子树包含1个节点,或者没有节点,直接返回true
    • 递推过程
      • 寻找左右子树的分界点:每次遇到比根节点小的值,向右移动指针pointer一次,直到遇到第一个大于根节点的值,这就是右子树的第一个节点的位置,将这个位置赋值给mid
      • 从分界点遍历到根节点:从mid开始继续移动指针pointer,每次遇到比根节点大的值,向右移动指针pointer一次。
    • 递归返回值
      • 根据最后pointer停留的位置判断,如果是BST的后序遍历序列,那么必然pointer指向序列的末尾,如果不是,返回false。
      • 判断左右子树是否是BST。返回二者的与。

    解答

    class Solution {
        public boolean verifyPostorder(int[] postorder) {
            return  recur(postorder,0,postorder.length - 1);
        }
    
        public boolean recur(int[] postorder,int start,int end){
            //当前子树只有一个节点(start == end) 或 当前子树是空树,一个节点都没有(start == end + 1)
            if(start >= end) return true;
            int pointer = start;
            while(postorder[pointer] < postorder[end]) pointer++;
            //右子树第一个节点
            int mid = pointer;
            while(postorder[pointer] > postorder[end]) pointer++;
            //如果是该子树是二叉搜索树,pointer一定指向最后一个节点
            if(pointer != end) return false;
            return recur(postorder,start,mid - 1) && recur(postorder,mid,end - 1);
        }
    }
  • 相关阅读:
    angular中transclude的理解
    node express中使用static的错误
    待研究———node中使用session时的id不断更改问题
    node 中mongoose使用validate和密码加密的问题
    exports 和 module.exports 的区别
    node.js开发错误——DeprecationWarning: Mongoose: mpromise
    Mongoose全面理解
    【js】JSON.stringify 语法实例讲解
    springboot+mybatis使用PageHelper分页
    连接mysql提示Establishing SSL connection without server's identity verification is not recommended错误
  • 原文地址:https://www.cnblogs.com/Howfars/p/13262246.html
Copyright © 2011-2022 走看看