图解LeetCode——剑指 Offer 07. 重建二叉树

简介: 图解LeetCode算法

一、题目

  • 输入某二叉树的前序遍历中序遍历的结果,请构建该二叉树并返回其根节点。
  • 假设输入的前序遍历和中序遍历的结果中都不含重复的数字

二、示例

2.1>示例 1:

输入】preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

输出】[3,9,20,null,null,15,7]

2.2> 示例 2:

输入】preorder = [-1], inorder = [-1]

输出】 [-1]

限制:

  • 0 <= 节点个数 <= 5000

三、解题思路

  • 根据题目描述,我们需要通过题目给出的一棵树的前序遍历中序遍历,来重建这棵二叉树。那么首先我们需要知道这两种遍历的方式是怎么样的:

前序遍历首先访问根结点,然后遍历左子树,最后遍历右子树

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

  • 那么,我们首先需要做的就是,通过前序遍历和后序遍历的遍历方式,来找到最近两层节点的关系,即:nodenode.leftnode.right;如下图所示,假设根节点所在前序遍历数组preorder的下标为:index,根据前序遍历规则我们可以得出如下结论:

子树根节点所在preorder数组中的位置index

左子树根节点所在preorder数组中的位置index + 1

右子树根节点所在preorder数组中的位置index + 左子树节点总和 + 1

  • 而我们怎么获得左子树节点总和呢?这时候,我们就可以根据中序遍历规则来计算出来了,我们假设某一个子树中序遍历数组为inorder,那么根节点所在位置是pos,某子树范围在[start, end]之间,那么就可以得出如下结论:

左子树节点总和pos - start

  • 主要逻辑说完了,由于我们可以根据中序遍历+子树根节点位置划分左子树节点集合右子树节点集合,那么通过递归调用就可以重塑这棵二叉树了
  • 解题思路说完了,我们还是举例来看一下重塑二叉树的过程。输入preorder = [3,9,20,15,7], inorder = [9,3,15,20,7],请参数如下图中的图解所示,看一下具体的处理过程:

四、代码实现

public class Solution {

   int[] preorder;

   HashMap<Integer, Integer> mark;

   public TreeNode buildTree(int[] preorder, int[] inorder) {

       if (preorder == null || inorder == null) return null;

       this.preorder = preorder;

       mark = new HashMap();

       for(int i = 0; i < inorder.length; i++)

           mark.put(inorder[i], i);

       return childNode(0, 0, inorder.length-1);

   }

   public TreeNode childNode(int root, int start, int end) {

       if (start > end) return null;

       TreeNode node = new TreeNode(preorder[root]);

       // 【子树根节点位置】index

       int index = mark.get(preorder[root]);

       // 【右子树根节点位置】index + 1

       node.left = childNode(root+1, start, index-1);

       // 【左子树根节点位置】index + 左子树长度(index-start)+ 1

       node.right = childNode(root+index-start+1, index+1, end);

       return node;

   }

}

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」

相关文章
|
3月前
【LeetCode 31】104.二叉树的最大深度
【LeetCode 31】104.二叉树的最大深度
31 2
|
3月前
【LeetCode 29】226.反转二叉树
【LeetCode 29】226.反转二叉树
27 2
|
3月前
【LeetCode 28】102.二叉树的层序遍历
【LeetCode 28】102.二叉树的层序遍历
22 2
|
3月前
【LeetCode 43】236.二叉树的最近公共祖先
【LeetCode 43】236.二叉树的最近公共祖先
25 0
|
3月前
【LeetCode 38】617.合并二叉树
【LeetCode 38】617.合并二叉树
22 0
|
3月前
【LeetCode 37】106.从中序与后序遍历构造二叉树
【LeetCode 37】106.从中序与后序遍历构造二叉树
28 0
|
3月前
【LeetCode 34】257.二叉树的所有路径
【LeetCode 34】257.二叉树的所有路径
28 0
|
3月前
【LeetCode 32】111.二叉树的最小深度
【LeetCode 32】111.二叉树的最小深度
22 0
|
5月前
|
存储 算法
二叉树进阶-学会层序遍历助你一次刷完leetcode10道题
文章深入探讨了二叉树的层序遍历方法,并展示了如何通过队列实现层序遍历的算法逻辑,同时指出掌握层序遍历技巧可以帮助解决LeetCode上的多道相关题目。
二叉树进阶-学会层序遍历助你一次刷完leetcode10道题
|
5月前
|
算法 Java
LeetCode第94题二叉树的中序遍历
文章介绍了LeetCode第94题"二叉树的中序遍历"的解法,使用递归实现了中序遍历的过程,遵循了"左根右"的遍历顺序,并提供了清晰的Java代码实现。
LeetCode第94题二叉树的中序遍历