Leetcode-每日一题【剑指 Offer 33. 二叉搜索树的后序遍历序列】

题目

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。

参考以下这颗二叉搜索树:

     5
    / \
   2   6
  / \
1   3

示例 1:

输入: [1,6,3,2,5]
输出: false

示例 2:

输入: [1,3,2,6,5]
输出: true

提示:

  1. 数组长度 <= 1000

解题思路

1.题目要求我们判断所给数组是不是某二叉搜索树的后序遍历结果,我们使用递归来实现。

2.首先我们观察一下正确的二叉搜索树的后序遍历的结果,

举个例子:Leetcode-每日一题【剑指 Offer 33. 二叉搜索树的后序遍历序列】_第1张图片

对于上面给出的二叉搜索树,我们可以观察到在遍历结果中根节点在最后一位,因此我们可以轻松的找到根节点root(6)。

Leetcode-每日一题【剑指 Offer 33. 二叉搜索树的后序遍历序列】_第2张图片 

因为二叉搜索树有一个特性就是根节点的左孩子都小于根节点,根节点的右孩子都大于根节点。因此当我们找到第一个大于根节点的元素时(7),就意味着我们找到了左右孩子的分界点。第一个大于根节点的元素之前 [3,4,5] 是根节点的左孩子,剩下的元素除了我们找到的最后一位是根节点,其余的都是根节点的右孩子 [7,8,9]。

Leetcode-每日一题【剑指 Offer 33. 二叉搜索树的后序遍历序列】_第3张图片 

 这个时候我们就要判断所给数组是否为正确,我们需要从找到的第一个大于根节点的元素,也就是 7 开始,判断除去根节点的后面的元素 [7,8,9] 中是否存在有小于根节点的元素。因为我们知道从7开始都是属于根节点的右子树肯定都是大于根节点的元素。若存在小于根节点的元素,那么就说明这个数组是有误的,我们就要返回false。

Leetcode-每日一题【剑指 Offer 33. 二叉搜索树的后序遍历序列】_第4张图片

当检查没有问题时,我们就需要递归得去判断6的左右子树是否正确,我们将左右子树传入递归函数中,左子树 [3,5,4] 的最后一个元素依旧是根节点(4),然后找到第一个大于根节点的元素(5),判断从此元素(5)开始向后遍历到根节点(4)的前一个元素是否有元素小于根节点(4),若没有就继续递归,直到所有元素都遍历结束。

代码实现

class Solution {
    public boolean verifyPostorder(int[] postorder) {
        if(postorder == null){
            return true;
        }
        return f(postorder, 0, postorder.length - 1);
    }
    boolean f(int[] postorder, int i, int j){
        if(i >= j){
            return true;
        }
        int root = postorder[j];
        int p = i;
        //获取第一个大于等于root的元素
        while(postorder[p] < root) p++;
        for(int k = p; k < j; k++){
            //查找p ~ j - 1是否存在小于root的元素
            if(postorder[k] < root){
                return false;
            }
        }
        return f(postorder, i, p - 1 ) && f(postorder, p, j - 1);

    }
}

测试结果

Leetcode-每日一题【剑指 Offer 33. 二叉搜索树的后序遍历序列】_第5张图片

 

你可能感兴趣的:(leetcode,算法,职场和发展,java)