难度:中等
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true
,否则返回 false
。假设输入的数组的任意两个数字都互不相同。
参考以下这颗二叉搜索树:
5
/ \
2 6
/ \
1 3
输入: [1,6,3,2,5]
输出: false
输入: [1,3,2,6,5]
输出: true
提示:
后序遍历 和 前序遍历 的特点一样,唯一不同的就是根结点一个在前,一个在后!
又有二叉搜索树的性质,二叉搜索树是有序的,对每一个树:
所以只要知道 根节点 就能确定哪些结点属于左子树,哪些属于右子树;而后序遍历刚好能得到根节点:
flag
:
flag
;flag
及其左边的应该都在左子树,左子树都应小于根节点,如果有不小于的根节点的数,则一定不是二叉搜索树,返回 false
;flag
切成两部分,左子树 和 右子树,再分别判断,只有同时都是二叉搜索树时,才返回 true
。C++
class Solution {
public:
bool verifyPostorder(vector<int>& postorder) {
if(postorder.size() == 0) return true;
return verify(postorder, 0, postorder.size() - 1);
}
bool verify(vector<int>& postorder, int fir, int lst){
if(fir >= lst) return true;
int flag = lst - 1;
while(flag >= fir && postorder[flag] > postorder[lst]){
flag--;
}
for(int i = flag - 1; i >= fir; i--){
if(postorder[i] > postorder[lst]) return false;
}
return verify(postorder, fir, flag) && verify(postorder, flag + 1, lst -1);
}
};
Java
class Solution {
public boolean verifyPostorder(int[] postorder) {
if(postorder.length == 0) return true;
return verify(postorder, 0, postorder.length - 1);
}
private boolean verify(int[] postorder, int fir, int lst){
if(fir >= lst) return true;
int flag = lst - 1;
while(flag >= fir && postorder[flag] > postorder[lst]){
flag--;
}
for(int i = flag - 1; i >= fir; i--){
if(postorder[i] > postorder[lst]) return false;
}
return verify(postorder, fir, flag) && verify(postorder, flag + 1, lst - 1);
}
}
verify
减去一个根节点,最差该二叉树退化为链表,递归调用了 n
次,且比较了 n
次。n
。题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!