[2021校招必看之Java版《剑指offer》-23] 二叉搜索树的后序遍历

一、题目描述

  【JZ23】输入一个整数数组,判断该数组是否是某二叉搜索树的后序遍历的结果。若是是则输出Yes,不然输出No。假设输入的数组的任意两个数字都互不相同。
  知识点:栈、树
  难度:☆☆☆java

二、解题思路

  二叉搜索树二叉树的一种,它是一棵空树,或者是具备下列性质的二叉树: 若它的左子树不空,则左子树上全部结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上全部结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。web

  所以,对于一个二叉搜索树的后序遍历数组来讲,数组的最后一个元素就是根节点。数组

  而后遍历数组的 [0, length-2] 元素,找出左右子树的分界点,依据是:分界点之前的元素均小于根节点,分界点之后(包含分界点)的元素均大于根节点。svg

  假设找到的分界点全部为 k,那么接着判断 [k, length-2] 中有没有小于根节点的,若是有,说明这个数组不是二叉搜索树的后序遍历序列。反之则是。spa

  判断完根节点后,接着判断 [0, k-1] 和 [k, length-2] 的状况,它们是根节点的左右子树。判断依据和上面同样。code

三、解题代码

package pers.klb.jzoffer.hard;

/** * @program: JzOffer2021 * @description: 二叉树的后序遍历序列 * @author: Meumax * @create: 2020-08-12 12:55 **/
public class SquenceOfBST {
    public boolean VerifySquenceOfBST(int[] sequence) {
        if (sequence == null || sequence.length == 0) return false;
        return verify(sequence, 0, sequence.length - 1);
    }

    /** * sequence 是后序遍历的结果,那么它最后一个元素确定为根节点 * * @param sequence * @param start * @param root * @return */
    private boolean verify(int[] sequence, int start, int root) {
        if (start >= root) return true;
        int key = sequence[root];
        int i;
        for (i = start; i < root; i++) {
            if (sequence[i] > key) break;   // 当 break 时,i 为 root 的左右子树分界线
        }
        // 判断右子树中有没有小于 key 的
        for (int j = i; j < root; j++) {
            if (sequence[j] < key) return false;
        }
        return verify(sequence, start, i - 1) && verify(sequence, i, root-1);
    }
}

四、解题心得

  本题属于寻找三种遍历和二叉树结构的关系。xml

  牢记三种遍历的特色,结合二叉树的结构,就能够找出突破点。好比本题的:二叉搜索树+后序遍历,就能够找出突破点在于:最后一个元素为根结点,而后前面元素跟根节点比大小就能够区分出左右子树。排序