LeetCode二叉搜索树的后序遍历序列
- 题目描述
- 题目分析
- 搜索二叉树
- 1、定义
- 2、性质
- 题目分析(续)
- 代码实现
- 总结
题目描述
题目分析
xxxx这道题的关键字是“搜索二叉树”、“后序遍历”。后序遍历大家应该都十分熟悉了,不熟悉的可以看我之前的博客二叉树的常见操作,但是搜索二叉树,估计大部分读者都不甚了解,所以我先把搜索二叉树的基本性质讲解一下。
搜索二叉树
1、定义
二叉搜索树是满足以下性质的二叉树。
1.非空左子树的所有结点的值小于其根结点的值;
2.非空右子树的所有值大于其根结点的值;
3.左右子树都是搜索二叉树。(递归定义)
2、性质
xxxx其实定义已经将搜索二叉树的性质阐述的十分清楚,我再简练得概述一下他最重要以及这道LeetCode题中考察的性质,就是按照后序顺序遍历搜索二叉树,那么会出想这样的序列【值均比根节点小的结点,值均比根节点大的结点,根节点】
如图:
题目分析(续)
xxxx有了以上的知识储备,我们就可以来仔细地分析这道题,就是通过上述提到的后序遍历搜索二叉树的性质,【小,大,根】,我们就可以通过比较得到左子树的序列,得到右子树的序列,左子树序列中所有值都小于根,右子树中所有值都大于根,一旦出现不符合的我们就可以断定,这个序列是不符合搜索二叉树的后序遍历的。如果符合,我们我们通过刚刚确定出来的左右子树,就可以递归的去检测左右子树,一直递归一直递归,直到所有子树都符合。
代码实现
上述分析只是答题思路,具体实现细节请仔细看代码+注释
1、说明一下递归子函数的参数:(1)sequence后序遍历序列的vector (2)start检测序列区段的开始位置 (3)检测序列区段的结束位置
2、我们从start开始,知道找到一个比根节点大的,这样就区分出哪一部分是左子树区间,哪一部分是右子树区间(从start遍历vector,直到找到大于根的,作为左右子树的分界)
3、这样我们就找到一段全比根小的左子树区间,然后再去检测剩下的右子树区间是否满足都比根大,如果有比根小的,说明就不符合搜索二叉树,就return false(再去遍历vector的后半段)
4、如果符合,那么我们就再去递归检测左右子树(此时重要的就是区间段的划分)
class Solution {
public:
//用于递归的子函数
bool _VerifySquenceOfBST(vector<int>& sequence,int start, int end)
{
//递归的出口,如果,start>=end,那么区间不存在或只有一个元素,说明没有子树了就是true
if(start>=end)
return true;
//保存根的值
int root = sequence[end];
int i = start;
//从start开始遍历,直到找到第一个比根大的值,作为左右子树的分界
while(sequence[i]<root)
{
i++;
}
//从刚刚找出的分界开始,到end-1(根的前一个位置)如果出现小于根的,说明不符合规定,就返回false
for(int j = i;j<end;j++)
{
if(sequence[j]<root)
return false;
}
//走到这里,就说明,本次检测符合搜索二叉树的后序遍历,我们就需要继续分别递归左右子树
//i是属于右子树的,所以左子树是【start,i-1】,右子树【i,end-1】
return _VerifySquenceOfBST(sequence,start,i-1) && _VerifySquenceOfBST(sequence,i,end-1);
}
bool VerifySquenceOfBST(vector<int> sequence) {
//如果vector为空,那么直接返回false
if(sequence.size() == 0)
return false;
//开始递归
return _VerifySquenceOfBST(sequence,0,sequence.size()-1);
}
};
总结
xxxx这道题考查了搜索二叉树的后序遍历,结果符合【左子树(小于根),右子树(大于根),根】这样的结构,然后就是,二叉树的递归算法。二叉树递归定义,递归解决。还有一个最重要的细节,就是边界的控制,刚刚,我们在找左右子树分界的时候,i是第一个比根大的,所以i处于的值是属于右子树的。。。。
xxxx本道LeetCode题目分享就到这里,如果各位读者有更好的解题方法或者思路,请在评论区评论,我们一起学习一起进步!
xxxx谢谢大家!!