题目描述:
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
参考以下这颗二叉搜索树:
示例 1:
输入: [1,6,3,2,5]
输出: false
示例 2:
输入: [1,3,2,6,5]
输出: true
提示:
数组长度 <= 1000
解题思路:
递归思想分治:
倒序遍历二叉搜索树的特点:最后一个节点是根节点,左子树节点的值都比根节点的值小,右子树节点的值都比根节点的值大。
分治思想:
当前这层(看做是一个输入的子树)满足了倒序遍历二叉搜索树的特点,同时要输入这一层的左子树和右子树,也要同时满足倒序遍历二叉搜索树的特点。当输入的某一层,子树的起点位置已经追上了根节点的位置,说明子树只有一个节点,则必然是满足要求的,直接返回true(这个是递归头)。
递归的输入是整个数组、子树的起点、子树根节点的位置。
代码(Java):
package verifyPostorder_33;
public class Solution {
public static void main(String[] args) {
int[] postorder = new int[]{5,7,6,9,11,10,8};
System.out.println(verifyPostorder(postorder));
}
public static boolean verifyPostorder(int[] postorder){
return recur(postorder, 0, postorder.length-1);
}
public static boolean recur(int[] postorder, int i, int j){
if(i >= j) return true; //递归头,如果输入子树的起点的位置追上了根节点的位置,说明这个子树只有一个根节点,肯定是符合条件的
int p = i; //先用p来记录输入子树的起点
while(postorder[p] < postorder[j]) p++; //从子树的起点出发,默认是左子树,则应该节点的值小于根节点的值,并一直用p找到右子树的起点
int m = p; //现有m记录右子树的起点
while(postorder[p] > postorder[j]) p++; //一个个点查找是否符合要求,如果能顺利到达根节点的位置,这一层是符合要求的
return p == j && recur(postorder, i, m-1) && recur(postorder, m, j-1); //查找这一层是否符合要求,如果是,则分别查看左子树和右子树
}
}