牛客网剑指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行)

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

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

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

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

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

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

 

posted @ 2020-04-06 10:10  少年π  阅读(274)  评论(0编辑  收藏  举报