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