面向小白的力扣105. 从前序与中序遍历序列构造二叉树

198 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

今天,我们继续搞算法。

题目描述

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

image.png

题目分析

这个题目是让我们构造二叉树并返回其根节点。

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] 输出: [3,9,20,null,null,15,7]

我们对结果进一步分析: preorder中可以看出根是3,inorder可以看出根是3,左子树是9, preorder中可以看出右子树是20,对应的根是20,左子树是15,右子树是7 进而还原整颗树。

解题思路

  • 确定操作对象:本题中,操作对象1个root
  • 确定操作条件:如果对象为空,返回空,如果遍历完了,返回空。
  • 确定操作过程:操作过程为,根据前序遍历和中序遍历特点,依次取出根和左右孩子,递归还原整棵树。
  • 确定结果返回:返回最终结果。

代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */

 /**
  * 我们先来分析一下这个条件,给定前序和中序分别如下:
  * preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
  * 我们要的结果是[3,9,20,null,null,15,7],3为根,9和20为其左右子树,依次类推。
  * 根据前序特点,preorder的0号元素为根,左右子树是从1号元素开始,到哪呢?从前序看不出来。
  * 因此,我们看中序,我们找到根,是1号元素,那一号元素之前是不是左子树?,同理我们可以还原出整棵树
  * 依次这么找,就还原了整棵树,最后把根节点返回皆可。
  */
 
class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        this.preorder = preorder;
        this.inorder = inorder;
        return build(0,preorder.length-1,0,inorder.length-1);
    }

    public TreeNode build(int pstart ,int pend , int istart, int iend){
        int imid=istart;
        if(pstart>pend) return null;
        TreeNode root = new TreeNode(preorder[pstart]);
        if(root == null) return null;
        while(inorder[imid] != root.val){
            imid++;
        }
        root.left = build(pstart+1,pstart+(imid-istart),istart,imid-1);
        root.right = build(pstart+(imid-istart)+1,pend,imid+1,iend);
        return root;
    }
    int[] preorder;
    int[] inorder;
}