Loading

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

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

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

《程序员代码面试指南》第45题 P148 难度:士★☆☆

原问题判断数组arr是否可能是搜索二叉树后序遍历的结果进阶问题通过数组arr重构二叉树

原问题的解法:根据二叉树后序遍历的顺序——左-右-根头节点的值一定是数组的最后一个元素然后将除最后一个元素的数组一分为二,满足左边数组的所有元素的值均小于最后一个元素的值,右边数组的所有元素的值均大于最后一个元素的值。如果不满足这种情况,说明这个数组一定不可能是搜索二叉树后序遍历的结果。将数组分为左边数组和右边数组,相当于将二叉树分出了左子树和右子树,然后再递归的进行如上判断即可。

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

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

学习一下题解代码的写法,通过less和more的值来判断左右子树都有or左右子树缺一个(less==-1 || more==end)。

进阶问题的分析与原问题同理,整个数组的最后一个值为二叉树头节点的值左部分都比头节点的值小,用来生成头节点的左子树右部分则为其右子树,通过递归生成整个二叉树

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

public Node posToBST(int[] posArr, int start, int end) {
    if (start > end) {
        return null;
    }
    Node head = new Node(posArr[end]);
    int less = -1;
    int more = end;
    for (int i = start; i < end; i++) {
        if (posArr[end] > posArr[i]) {
            less = i;
        } else {
            more = more == end ? i : more;
        }
    }
    head.left = posToBST(posArr, start, less);
    head.right = posToBST(posArr, more, end - 1);
    return head;
}

另外需要注意的是,题解的代码中自始至终都只用到了一个数组递归传递的是索引值。而我自己写的代码中使用了Arrays.copyOfRange()方法,造了很多个数组,多余的空间有点浪费。。所以能省则省

posted @ 2022-02-15 21:04  幻梦翱翔  阅读(48)  评论(0)    收藏  举报