千家信息网

LeetCode题解之如何重建二叉树

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容主要讲解"LeetCode题解之如何重建二叉树",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"LeetCode题解之如何重建二叉树"吧!题目输入某二
千家信息网最后更新 2026年11月03日LeetCode题解之如何重建二叉树

本篇内容主要讲解"LeetCode题解之如何重建二叉树",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"LeetCode题解之如何重建二叉树"吧!

题目

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历 preorder = [3,9,20,15,7]

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

返回如下的二叉树:

 3  / \ 9  20   /  \  15   7

题解

上周说过 前序遍历和后序遍历,其实这种前序、中序、后序都是相对于中间节点的处理顺序。

比如先序遍历的顺序就应该是:

[ 根节点 | 左子树 | 右子树 ]

同理,中序遍历的顺序就是:

[ 左子树 | 根节点 | 右子树 ]

所以前序遍历的第一个元素肯定就是 根节点。

然后,我们就能在 中序遍历找到根节点,并正确把中序遍历区分为三部分,也就是左子树中序、根节点、右子树中序。

举个例子:

如果只有三个元素,那么到这里就能结束了,因为树已经能画出来了。

比如前序是【3,9,20】,中序是【9,3,20】

我们根据中序知道了根节点3,然后在中序中就能区分出左子树节点9,根节点3,右子树节点20。

现在我们扩散开,如果不止3个节点呢?

举例2:

如果是5个元素,比如前序是[3,9,20,15,7],中序是[9,3,15,20,7]

经过第一次分割,我们把中序分成了左子树9,根节点3,右子树【15,20,7】

这时候,右子树该怎么分呢?跟节点是什么呢?又不知道了。

所以这时候要再联系到前序遍历,根据我们所知道的左子树节点,得出前序中右子树应该为【20,15,7】,所以右子树的根节点为20。

总之,就是前序和中序互相帮助,最终通过递归完成我们树的构建。

解法1

解法1就是依靠递归。

递归的过程就是找出每个父节点的左子树节点和右子树节点,一共三个值。

而最终的取值都是从前序列表中取值,其实就是取每个小树的父节点。

而中序遍历数组的作用就是找到 每次父节点在中序遍历数组中的位置。

得出如下算法。

/**  * Definition for a binary tree node.  * public class TreeNode {  *     int val;  *     TreeNode left;  *     TreeNode right;  *     TreeNode(int x) { val = x; }  * }  */ class Solution {     int[] preorder;     HashMap dic = new HashMap<>();     public TreeNode buildTree(int[] preorder, int[] inorder) {         this.preorder = preorder;         for(int i = 0; i < inorder.length; i++)             dic.put(inorder[i], i);         return recur(0, 0, inorder.length - 1);     }     TreeNode recur(int root, int left, int right) {         if(left > right) return null;                 //根节点                           TreeNode node = new TreeNode(preorder[root]);            //分割点             int i = dic.get(preorder[root]);                 node.left = recur(root + 1, left, i - 1);          node.right = recur(root + i - left + 1, i + 1, right);          return node;           } }

其中每次取右子树的根节点需要注意:

左子树的节点数为i-left。

所以在前序遍历数组中,左子树的节点+根节点位置,就是左子树的最后一个节点位置,也就是root+i-left。

最后得出右子树的根节点为:root + i - left + 1

而递归的结束条件就是,左右子树节点相遇,也就是left>right。

时间复杂度

O(n),n为树的节点数量。

空间复杂度

O(N),用到了HashMap。

解法2

还有一种办法叫做迭代方法,这个方法挺巧妙的,当时也是看了很久的官方解答才想明白的,哈哈。

它的主要思想是理解前序遍历和中序遍历的规则,然后一个个从前序遍历中取值,并放到合适的位置。

比如以下这个二叉树:

        3        / \       9  20      /  /  \     8  15   7    / \   5  10  / 4

前序遍历,可以发现是首先把最左边的节点列出来,也就是 3,9,8,5,4

而中序列表是反着来的,从最左边的下面开始,往上列,如果发现某个节点有右子节点,就开始往右边列。

比如 4,5,8。这时候发现8有右子节点,那么就开始数 10 ,然后继续最左边往上,9,3。

最后列一下完整的前序和中序:

preorder = [3, 9, 8, 5, 4, 10, 20, 15, 7] inorder = [4, 5, 8, 10, 9, 3, 15, 20, 7]

总之,前序是从左边列开始,从上往下排。中序就是从左边列开始,从下往上排。

看看代码:

class Solution {     public TreeNode buildTree(int[] preorder, int[] inorder) {         if (preorder == null || preorder.length == 0) {             return null;         }         TreeNode root = new TreeNode(preorder[0]);         Deque stack = new LinkedList();         stack.push(root);         int inorderIndex = 0;         for (int i = 1; i < preorder.length; i++) {             int preorderVal = preorder[i];             TreeNode node = stack.peek();             if (node.val != inorder[inorderIndex]) {                 node.left = new TreeNode(preorderVal);                 stack.push(node.left);             } else {                 while (!stack.isEmpty() && stack.peek().val == inorder[inorderIndex]) {                     node = stack.pop();                     inorderIndex++;                 }                 node.right = new TreeNode(preorderVal);                 stack.push(node.right);             }         }         return root;     } }

if语句是为了找到左列最后一个节点,比如上述例子中的4。

while循环是当发现有右节点的时候,要找到右节点的父节点,然后添加进去。

到此,相信大家对"LeetCode题解之如何重建二叉树"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

节点 子树 就是 题解 也就是 位置 递归 元素 数组 方法 解法 顺序 复杂 三个 例子 内容 复杂度 序列 序列表 结果 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 湖北九亚互联网络科技有限公司 为想互联网科技怎么样 互联网科技深圳 智能科技公司是互联网公司吗 中国 科技 互联网 碳银互联网科技 鑫亿盛互联网科技 互联网科技logo 天下捷融互联网科技 兼蜜互联网科技 滨湖区互联网智能科技产品供应 银川新华互联网科技学校地址 彤创互联网科技有限公司 湖南一路畅行互联网科技 苏州铭阳互联网科技有限公司 搜狐科技互联网 恒生互联网科技指数跳水 互联网科技的全部知识 互联网与数字科技关系 九思连强互联网电子科技有限公司 上海喔噻互联网科技有限公司 互联网科技公司税收优惠 金融科技 互联网金融 致聘互联网科技 中国互联网金融科技基金 银川新华互联网科技学校地址 成都玖崟互联网科技有限公司乐商圈怎么样 互联网大会黑科技排名 天津腾达互联网科技有限公司 宇信科技在杭州互联网排第几
0