《程序员代码面试指南》根据后序数组重建搜索二叉树——java实现

根据后序数组重建搜索二叉树

题目描述:

给定一个整型数组arr,已知其中没有重复值,判断arr是否可能是节点值类型为整型的搜索二叉树后序遍历的结果。
进阶:
如果整型数组arr中没有重复值,且已知是一棵搜索二叉树的后 序遍历结果,通过数组arr重构二叉树。

题目难度:

easy

题目思路:

题目一:
已知给定一个无重复元素的数组,判断数组是否是二叉树后序遍历的结果。
1、已知后序遍历的顺序为左右中,则数组的最后一位元素为二叉树的头结点,且比该节点小的为左子树,比该节点大的为右子树;
2、找到比最后一位小的最右节点,并找到比最后一位大的最左节点;如果最右节点的下一个节点为最后节点,则没有右子树,或者最左节点为开始节点,则没有左子树;这两种情况直接进行下一步,即最后位置向前移一位;
3、如果最右节点加1不等于最左节点,直接返回false;
4、最终通过递归,判断左子树和右子树是否分别为二叉搜索树。

进阶版:
要重构二叉树,只需要找到后序遍历中的左右子树分界点,并递归构建整颗树。

代码实现:

public static boolean isPosArray(int[] arr){
        if (arr == null || arr.length == 0){
            return false;
        }
        return isPost(arr, 0, arr.length - 1);
    }

    public static boolean isPost(int[] arr, int start, int end){
        if(start == end){
            return true;
        }
        int lessRight = -1;
        int moreLeft =  end;
        for (int i = start; i < end; i++){
            if (arr[i] < arr[end]){
                lessRight = i;
            }else {
                moreLeft = moreLeft == end ? i : moreLeft;
            }
        }
        if (moreLeft == end - 1 || lessRight == start){
            return isPost(arr, start,end - 1);
        }
        if (moreLeft != lessRight - 1){
            return false;
        }
        return isPost(arr, start, moreLeft) && isPost(arr,lessRight, end - 1);
    }

进阶:

  public static class Node {
        Node left;
        Node right;
        int value;

        public Node(int value) {
            this.value = value;
        }
    }

    public static Node posArrayToBST(int[] arr) {
        if (arr == null) {
            return null;
        }
        return posToArray(arr, 0, arr.length - 1);
    }

    public static Node posToArray(int[] arr, int start, int end) {
        if (start > end) {
            return null;
        }
        Node head = new Node(arr[end]);
        int lessRight = -1;
        int moreLeft = end;
        for (int i = start; i < end; i++) {
            if (arr[i] < arr[end]) {
                lessRight = i;
            } else {
                moreLeft = moreLeft == end ? i : moreLeft;
            }
        }
        head.left = posToArray(arr, start, lessRight);
        head.right = posToArray(arr, moreLeft, end - 1);
        return head;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值