输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
参考以下这颗二叉搜索树:
5
/ \
2 6
/ \
1 3
示例 1:
输入: [1,6,3,2,5]
输出: false
示例 2:
输入: [1,3,2,6,5]
输出: true
提示:
数组长度 <= 1000
解题思路:递归分治
后序遍历序列:左子树 | 右子树 | 根结点
二叉搜索树:左子树中所有结点的值都小于根结点,右子树中所有结点的值都大于根结点
从左到右遍历后序遍历序列,找到第一个大于根结点的下标m,[0,m-1]为左子树,[m,j-1]为右子树。判断右子树是否都大于根结点就可以了。之后用递归重复判断其剩下的所有子树。
算法流程:
1.返回判断函数recur的判断结果(把后序遍历序列,下标0,该序列的最后一个坐标)
2.定义recur函数
递归终止条件:i>=j (表示判断结束)
返回true (只剩一个元素无需判断)
定义变量p=i
用p存储第一个大于根结点的下标
定义m=p
判断右子树是否全部大于根结点
返回判断结果和递归剩下的左右子树
代码:
class Solution {
public:
bool verifyPostorder(vector<int>& postorder) {
return rescur(postorder,0,postorder.size()-1);
}
bool rescur(vector<int> postorder,int i,int j) {
if(i>=j) return true;
int p=i;
while(postorder[p]<postorder[j])
p++;
int m=p;
while(postorder[p]>postorder[j])
p++;
return p==j &&
rescur(postorder,i,m-1) &&
rescur(postorder,m,j-1);
}
};
运行步骤:
[1,3,2,6,5]
i=0,j=4,m=3,p=j=4 返回true
&&
i=0,j=2,m=1,p=j=2
i=0,j=0,返回true
&&
i=3,j=3,返回true
返回true&&true&&true=true