leetcode刷题(133)——剑指 Offer 07. 重建二叉树
创始人
2024-02-15 08:22:43
0

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。

假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

示例 1:
在这里插入图片描述

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

示例 2:

Input: preorder = [-1], inorder = [-1]
Output: [-1]

解题思路:

前序遍历性质: 节点按照 [ 根节点 | 左子树 | 右子树 ] 排序。
中序遍历性质: 节点按照 [ 左子树 | 根节点 | 右子树 ] 排序。

以题目示例为例:

前序遍历划分 [ 3 | 9 | 20 15 7 ]
中序遍历划分 [ 9 | 3 | 15 20 7 ]
根据以上性质,可得出以下推论:

前序遍历的首元素 为 树的根节点 node 的值。
在中序遍历中搜索根节点 node 的索引 ,可将 中序遍历 划分为 [ 左子树 | 根节点 | 右子树 ] 。
根据中序遍历中的左(右)子树的节点数量,可将 前序遍历 划分为 [ 根节点 | 左子树 | 右子树 ] 。

在这里插入图片描述
通过以上三步,可确定 三个节点 :1.树的根节点、2.左子树根节点、3.右子树根节点。

根据「分治算法」思想,对于树的左、右子树,仍可复用以上方法划分子树的左右子树。

分治算法解析:
递推参数: 根节点在前序遍历的索引 root 、子树在中序遍历的左边界 left 、子树在中序遍历的右边界 right ;

终止条件: 当 left > right ,代表已经越过叶节点,此时返回 nullnull ;

递推工作:

建立根节点 node : 节点值为 preorder[root] ;
划分左右子树: 查找根节点在中序遍历 inorder 中的索引 i ;
为了提升效率,本文使用哈希表 dic 存储中序遍历的值与索引的映射,查找操作的时间复杂度为 O(1)O(1) ;

构建左右子树: 开启左右子树递归;
在这里插入图片描述
TIPS: i - left + root + 1含义为 根节点索引 + 左子树长度 + 1

返回值: 回溯返回 node ,作为上一层递归中根节点的左 / 右子节点;

复杂度分析:
时间复杂度 O(N): 其中 N 为树的节点数量。初始化 HashMap 需遍历 inorder ,占用 O(N) 。递归共建立 N个节点,每层递归中的节点建立、搜索操作占用 O(1) ,因此使用 O(N)时间。
空间复杂度 O(N) : HashMap 使用 O(N)额外空间;最差情况下(输入二叉树为链表时),递归深度达到 N ,占用 O(N)的栈帧空间;因此总共使用 O(N) 空间。

注意:本文方法只适用于 “无重复节点值” 的二叉树。

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;                                           // 回溯返回根节点}
}

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...