zoukankan      html  css  js  c++  java
  • 牛客网剑指offer第23题——二叉搜索树的后续遍历序列

    题目:

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

    思路分析:

    由于是二叉搜索树,即BST树。则其中序遍历就是按照大小顺序排列的。后续遍历就是:先遍历左子树,再遍历右子树,再遍历根节点。而要遍历的树是BST树,则左子树所有节点value<根节点<右子树。即如下图所示:

     我们可以看到,左子树是小于根节点的,右子树是大于根节点的。

    那么,我们该如何判断是不是后续遍历呢?也就是数组到底符合什么规律才是后续遍历?看下图:

     上图表明,我们索引所有小于node的数作为当前node的左子树value,大于node的数作为右子树value。在正常情况下:这个索引index应该等于array.size-1;也即是node 前面的数恰好被分成了两部分;比如上图下面那个例子。没有访问到结尾,就要结束了,显然,这并不是后续遍历。

    当对当前node进行了判断之后,对其左右子树做同样的判断。

    先给出代码:再给出关于递归的一些总结:

     1 class Solution {
     2 public:
     3     bool VerifySquenceOfBST(vector<int> sequence) {
     4       //注意题设有说明是二叉搜索树
     5         int length  = sequence.size();
     6         if(length < 1)
     7             return false;
     8         if(length == 1)
     9             return true;
    10         vector<int>left,right;
    11         int index = 0;
    12         int node = sequence[length-1];//头节点
    13         while(sequence[index] < node)
    14         {
    15             left.push_back(sequence[index]);
    16             index++;
    17         }
    18         while(sequence[index] > node)
    19         {
    20             right.push_back(sequence[index]);
    21             index++;
    22         }
    23         if(index < (length-1))
    24             return false;
    25         if(left.size() == 0)
    26             return VerifySquenceOfBST(right);//y要考虑有一侧为空的情况
    27         else if(right.size() == 0)
    28             return VerifySquenceOfBST(left);
    29         else
    30         return VerifySquenceOfBST(left)&&VerifySquenceOfBST(right);
    31     }
    32 };

    分析:我并没有像其他人一样采用两个函数递归调用,而是只用了一个函数,我的思想是什么呢?

    先处理数组为空,此时返回false;因为我知道要将输入数组划分为左右子树,并递归进行判断。当然了25-30行的代码需要注意的是:假如递归到一定程度,左子树为空,或者右子树为空,我们应该判断另一棵树;当然了如果两者都不为空,则都要判断。最终,我们给出了递归的终止条件:也就是第8行的代码,即数组中只有一个元素,即只有一树节点,此时返回true。

    根据上个题目。我们对递归解决bool返回值的问题做一个总结

    第一步:边界判断(当然了,这是所有的时候都要做的,上述代码6-7行)

    第二步:给出递归子结构时输入参数的表达式(比如上述中的left和right,上述代码10-22行)

    第三步:给出当前步骤中,返回失败的条件(上述代码23-24行)

    第四步:给出子结构递归的表达式(上述代码25-30行)

    第五步:给出递归终止条件(该问题有解的条件,上述代码8-9行)

    上述步骤中,第二步和第四步是非常重要的,甚至是可能比较困难的。

    从上述步骤中,抽象出我理解的一般递归的步骤:

    第一步:给出递归子结构时输入参数的表达式

    第二步:给出子结构递归的表达式

    第三步:给出递归终止条件

    我认为处理递归问题时候,应该严格按照上述三个步骤来,并且顺序不能搞反了!

  • 相关阅读:
    GridView Footer页脚统计实现多行
    Windows cmd 启动 tomcat 中文乱码问题
    git
    CentOS 的 dnf 命令
    不知道是否是wcf 的一个bug
    图像卷积与滤波的一些知识点
    Phaser开源2d引擎 javascript/html5游戏框架
    关于Ldoc
    自写vim插件ldoc.vim,提供智能的lua注释代码补全
    svn diff 使用 vimdiff 作为比较差异工具
  • 原文地址:https://www.cnblogs.com/shaonianpi/p/12640796.html
Copyright © 2011-2022 走看看