leetcode106-从中序与后序遍历序列构造二叉树

原题

根据一棵树的中序遍历与后序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3]

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

解法

思想

根据后序遍历最后一个元素是根、中序遍历以根为中心划分左子树和右子树的特点,递归构造左子树和右子树。

代码

我们逐渐来优化时间复杂度:

第一版,较好懂:

class Solution {
    public int indexOf(int target,int[] order){
        for(int i = 0;i<order.length;i++){
            if(order[i] == target) return i;
        }
        return -1;
    }
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(postorder.length == 0) return null;
        TreeNode root = getUnit(inorder,postorder);
        return root;
    }
    public TreeNode getUnit(int[] inorder,int[] postorder){
        if(postorder.length == 0) return null;
        TreeNode root = new TreeNode(postorder[postorder.length-1]);
        int index = indexOf(postorder[postorder.length-1],inorder);
        int[] leftpartInorder = Arrays.copyOfRange(inorder,0,index);
        int[] rightpartInorder = Arrays.copyOfRange(inorder,index+1,inorder.length);
        int leftCount = leftpartInorder.length;
        int[] leftpartPostorder = Arrays.copyOfRange(postorder,0,leftCount);
        int[] rightpartPostorder = Arrays.copyOfRange(postorder,leftCount,postorder.length-1);
        root.left = getUnit(leftpartInorder,leftpartPostorder);
        root.right = getUnit(rightpartInorder,rightpartPostorder);
        return root;
    }
}

第二版,不用再复制数组,直接在原数组上操作:

class Solution {
    int[] inorderGlobal;
    int[] postorderGlobal;
    public int indexOf(int target,int start,int end){
        for(int i = 0;i<end-start;i++){
            if(inorderGlobal[i+start] == target) return i+start;
        }
        return -1;
    }
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        inorderGlobal = inorder;
        postorderGlobal = postorder;
        if(postorder.length == 0) return null;
        TreeNode root = getUnit(0,inorder.length,0,postorder.length);
        return root;
    }
    public TreeNode getUnit(int inorderStart,int inorderEnd,int postorderStart,int postorderEnd){
        if(postorderEnd==postorderStart) return null;
        TreeNode root = new TreeNode(postorderGlobal[postorderEnd-1]);
        int index = indexOf(postorderGlobal[postorderEnd-1],inorderStart,inorderEnd);
        int leftCount = index-inorderStart;
        root.left = getUnit(inorderStart,index,postorderStart,leftCount+postorderStart);
        root.right = getUnit(index+1,inorderEnd,postorderStart+leftCount,postorderEnd-1);
        return root;
    }
}

第三版,既然经常要用查找元素在中序遍历中的位置,可以不需要使用indexOf函数,而是一开始则将对应关系保存在哈希表中:

class Solution {
    int[] postorderGlobal;
    Map<Integer,Integer> map;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        postorderGlobal = postorder;
        map = new HashMap<>();
        for(int i = 0;i < inorder.length; i++) map.put(inorder[i], i);
        if(postorder.length == 0) return null;
        TreeNode root = getUnit(0,inorder.length,0,postorder.length);
        return root;
    }
    public TreeNode getUnit(int inorderStart,int inorderEnd,int postorderStart,int postorderEnd){
        if(postorderEnd==postorderStart) return null;
        TreeNode root = new TreeNode(postorderGlobal[postorderEnd-1]);
        int index = map.get(postorderGlobal[postorderEnd-1]);
        int leftCount = index-inorderStart;
        root.left = getUnit(inorderStart,index,postorderStart,leftCount+postorderStart);
        root.right = getUnit(index+1,inorderEnd,postorderStart+leftCount,postorderEnd-1);
        return root;
    }
}

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/leetcode106-%e4%bb%8e%e4%b8%ad%e5%ba%8f%e4%b8%8e%e5%90%8e%e5%ba%8f%e9%81%8d%e5%8e%86%e5%ba%8f%e5%88%97%e6%9e%84%e9%80%a0%e4%ba%8c%e5%8f%89%e6%a0%91/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年1月12日
下一篇 2020年1月13日

相关推荐

  • leetcode69-x的平方根

    原题 实现 int sqrt(int x) 函数。 计算并返回 x 的平方根,其中 x 是非负整数。 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。 示例1: 输入:…

    算法 2019年12月30日
    040
  • leetcode138-复制带随机指针的链表

    这道题和leetcode133-克隆图有异曲同工之妙。 原题 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。 要求返回这个链表的深拷贝。…

    2019年12月17日
    0330
  • leetcode260-只出现一次的数字III

    原题 给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。 示例: 输入: [1,2,1,3,2,5] 输出: [3,5…

    算法 2020年4月28日
    0150
  • leetcode32-最长有效括号

    原题 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。 示例 1: 输入: "(()" 输出: 2 解释: 最长有效括号子串为 "()" 示例 2…

    算法 2020年6月12日
    0160
  • leetcode123-买卖股票的最佳时机III

    原题 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意: 你不能同时参与多笔交易(你…

    算法 2020年6月16日
    01540
  • 海量数据-两种方法解决top k问题

    假如提供一百万个数据(甚至更大)的无序数组,如何从中获取最大的k个元素? 最容易想到的是先降序排序然后获取前k个元素,那假设我们用最常用的O(nlogn)级别的排序算法,要获取to…

    2020年4月4日
    0230
  • leetcode542-01矩阵

    原题 给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。 示例1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 …

    2019年12月13日
    080
  • 海量数据算法-BitMap介绍和实现

    作为一个有素质的程序员,在面试中(不是) 难免会遇到海量数据相关的问题,之前有注意过java.util下面有一个BitSet数据结构,但不是很明白是做什么用的。今天就来研究一下它背…

    算法 2020年2月27日
    04070
  • leetcode376-摆动序列

    原题 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。 例如, [1,7,4,9,…

    算法 2020年2月18日
    0120
  • 剑指offer59-队列的最大值

    原题(来源Leetcode) 请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的时间复杂度…

    算法 2020年3月7日
    0130

发表回复

登录后才能评论