当前位置: 首页剑指offer刷题第七期问题详情 【二叉树专题】剑指 Offer 07. 重建二叉树 本问题对应课程链接:剑指offer刷题第七期 要求: 1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路。 2、给出你代码所用的时间复杂度和空间复杂度
共以下 22 个回答
递归:
1. 数组为空返回NULL,数组仅一个元素返回root
2. 根据前序第一个元素的值,切割中序数组
3. 递归左右子树,最后整体返回。
根据前序遍历和中序遍历的性质
解题思路
前序遍历:第一个节点一定就是根节点
中序遍历:根节点左边的数据全部都是左子树,右边的数据全部都是右子树
后序遍历:最后一个节点一定就是根节点
题目给了前序+中序,可以根据前序获取根节点,拉着根节点去中序里面拆分左右子树,然后继续通过递归找出左右子树的根节点。
题解1【不推荐解法】拆分了原本的2个数组,空间浪费了,其实不需要拆分
题解2【不去拆分数组,并且使用Map去缓存number对应的index】
方法:通过找到root在两次遍历结果间的位置关系来确定左右子树的长度/元素和顺序。
注意root_pos – l2 是左边子树的长度,这点比较容易弄错。
time O(n) space O(n)
需要再多画图加深一下理解
根据中序遍历及前序遍历,确认各个节点的对应关心
递归时只需要记录preorder数组的左右子树根节点位置以及inorder数组左右子树的范围。分别用root,l,r表示。利用哈希表可以很方便的找到分界点。因为preorder数组是前序遍历的结果,所以左子树的根节点为root+1。右子树的根节点为root+左子树的长度+1。
时间复杂度O(N),空间复杂度O(N)。
时间o(n)
空间o(n)
错误点注意:
这里需要注意:
int preindex = preStart + (rootindex - inStart);刚开始写的是:
int preindex = preStart + rootindex;是不对的,rootindex只是恰好在本题第一个测试用例代表了左子树的node个数,一旦inStart!=0,则无法代表左子树的node个数了,会fail,此处需要注意!/**
* 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;
* }
* }
*/
class Solution {
int[] preorder;
HashMap<Integer, Integer> hmap = new HashMap<>();
}//用map记录preorder和inorder之间的关系
先序的头是根节点,再中序中找到根节点,然后递归构建二叉树
补充一个中序后序建立二叉树的题目
On ON
class Solution {
HashMap<Integer, Integer> inMap = new HashMap();
int[] preorder;
public TreeNode deduceTree(int[] preorder, int[] inorder) {
this.preorder = preorder;
for(int i = 0; i < inorder.length; i++){
inMap.put(inorder[i], i);
}
return build(0, 0, inorder.length-1);
}
}
时间:O(n)
空间:O(n)
时间复杂度O(n),空间复杂度O(n)
//先序遍历第一个节点一定是根结点,找到跟节点在中序遍历中的位置,左边是根结点左子树,右边为右子树,递归构建树,时间复杂度和空间复杂度都是O(N).
class Solution {
private Map<Integer, Integer> inorderIndexMap;
private int preorderIndex;
public TreeNode deduceTree(int[] preorder, int[] inorder) {
inorderIndexMap = new HashMap<>();
preorderIndex = 0;
for (int i = 0; i < inorder.length; i++) {
inorderIndexMap.put(inorder[i], i);
}
}
思路:记录中序遍历序列及其索引的映射,用于后续计算左子树长度使用,确定左右子树的区间。递归的构建二叉树。
时间复杂度:O(n)
空间复杂度:O(n)
时间复杂度 O(N)
空间复杂度 O(N)
递归,重点是边界的划定
思路:看完讲解视频之后写出来的。主要就是碰到这类问题的时候,没有思路或者怕理不清的时候,一定要画图
画图标注下标,一步步推理,可以看出来结论和规律,然后进行递归
思路: 先序遍历首先遍历到的结点为父节点,并在中序遍历中找到对应节点位置,中序结点左侧即为左子树结点,中序结点右侧即为右子树结点,递归构造即可