• 二叉搜索树的后序遍历序列


    来源:牛客网 《剑指offer》

    题目描述

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

    先复习一下二叉搜索树(来自维基百科):

    二叉查找树英语:Binary Search Tree),也称二叉搜索树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树

    1. 任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
    2. 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
    3. 任意节点的左、右子树也分别为二叉查找树;
    4. 没有键值相等的节点。

    后序遍历是先访问左子树,然后右子树,最后根节点。

    下图的后序遍历序列为:4,6,7,5,12,20,15,10.

    因此思路是,先遍历序列,与根节点比较,将序列分为左子树和右子树,其中左子树的值都必须<根节点,右子树的值都必须>根节点。递归上述过程。

    思路不难,但是我写了好长时间,主要是一些边界条件没注意。

    AC代码:

     1 public class TT {
     2     static int time=0;
     3 
     4     public static void main(String[] args) {
     5         int[] a={4,6,7,5,12,20,15,10};
     6         // int[] a={5,4,3,2,1};
     7 
     8         System.out.println(VerifySquenceOfBST(a));
     9     }
    10 
    11 
    12     public static boolean VerifySquenceOfBST(int [] sequence) {
    13         //if(sequence==null) return false;
    14         if(sequence.length==0) return false;
    15         return Core(sequence, 0, sequence.length-1);
    16     }
    17 
    18     public static boolean Core(int[] a, int start, int end){
    19         //if(start==end) return true;
    20         if(start>=end) return true;
    21         
    22         int mid=getMid(a, start, end);
    23         System.out.println(start+" "+end+" "+mid);
    24         for(int i=start; i<= mid; ++i) 
    25             if(a[i]>a[end]) return false;
    26         for(int i=mid+1; i<= end-1; ++i) 
    27             if(a[i]<a[end]) return false;
    28 
    29         return (Core(a, start, mid) && Core(a, mid+1, end-1));
    30     }
    31 
    32     // 4 6 7 5 | 12 20 15 10
    33     // root=10
    34     public static int getMid(int[] a, int start, int end){
    35         for(int i=start; i<=end; ++i){
    36             if(a[i]>a[end]) {
    37                 // if(i==start) return start; // left subtree is null
    38                 // else return i-1;
    39                 return i-1; // if left subtree is null, i.e. i=0, return value is -1
    40             }
    41         }
    42 
    43         return end-1; // if the right subtree is null 
    44     }
    45 }
    View Code

    碰到的细节问题有:

    (1)数组==null 与 长度为0并不一样

    //if(sequence==null) return false;
    if(sequence.length==0) return false;
    
    int[] a={};
    a 的长度为0,但a!=null

    (2)边界条件

    //if(start==end) return true;
    if(start>=end) return true;
    for 循环初始化语句i=start;而不是i=0;
    43行处return end-1,而不是 a.length-1.

    (3) getMid 函数用于将序列分为左子树和右子树,返回左子树的最后一个节点的索引。

    当左子树为空时,应该返回-1. 而我一开始的代码返回0. (上述代码中已注释掉)。

  • 相关阅读:
    SPOJ_DSUBSEQ Distinct Subsequences
    ZOJ 3791 An easy game DP+组合数
    UVALive 4287 SCC-Tarjan 加边变成强连通分量
    ZOJ 3795 Grouping 强连通分量-tarjan
    HDU 4915 多校5 Parenthese sequence
    ZOJ 3790 Consecutive Blocks
    HDU 4866 多校1 主席树+扫描线
    求最大值及其下标
    查找整数
    抓老鼠
  • 原文地址:https://www.cnblogs.com/duanguyuan/p/5704342.html
Copyright © 2020-2023  润新知