当前位置: 首页剑指offer刷题第三期问题详情 【二叉树专题】剑指 Offer 07. 重建二叉树 本问题对应课程链接:剑指offer刷题第三期 要求: 1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路。 2、给出你代码所用的时间复杂度和空间复杂度
共以下 36 个回答
“`java indexByValue = new HashMap<>();
关键在于分治
class Solution {
Map
public TreeNode deduceTree(int[] preorder, int[] inorder) {
if (preorder == null || inorder == null || preorder.length == 0) {
return null;
}
for (int i = 0; i < inorder.length; i++) { indexByValue.put(inorder[i], i); } return recur(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); }
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
Map<Integer,Integer> map = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preordernull||preorder.length0){
return null;
}
for(int i=0;i<preorder.length;i++){
map.put(inorder[i],i);
}
return recur(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
}
根据中序遍历递归求左右子树
“`java map=new HashMap();
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
Map
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder==null || inorder==null){
return null;
}
for(int i=0;i
return f(preorder,0,preorder.length-1,inorder,0,inorder.length-1); }TreeNode f(int[] preorder,int l1,int r1,int[] inorder,int l2 ,int r2){
// 当左右结点为空时停止
if(l1>r1&&l2>r2){
return null;
}
TreeNode root= new TreeNode(preorder[l1]);
int i=map.get(preorder[l1]);
root.left=f(preorder,l1+1,l1+(i-l2),inorder,l2,i-1);
root.right=f(preorder,l1+(i-l2)+1,r1,inorder,i+1,r2);
return root;
}
}
一开始觉得很难,后面理解了还好,就是要拆解问题,然后 停止条件那里很巧妙。
时间复杂度O(n),空间复杂度O(n)
【思路】利用前序后序的特性递归实现
【时间复杂度】由于要遍历inorder数组找到root,复杂度O(nlogn)(如果用map数据结构映射value到idx会变为O(n),但对应的空间消耗会增加)
【空间复杂度】O(n)
通过递归来将问题分解,再逐个解决
构建二叉树的思路如下:
在中序遍历的结果中,找到根节点的位置。根据中序遍历的性质,根节点的左侧为左子树的中序遍历结果,右侧为右子树的中序遍历结果。
根据中序遍历的结果,可以确定左子树和右子树的节点数量。在前序遍历的结果中,根节点后面的节点是左子树的前序遍历结果,再之后的节点是右子树的前序遍历结果。
递归地构建左子树和右子树,重复步骤1到步骤3,直到遍历完所有的节点。
返回根节点。
以上是构建二叉树的基本思路,通过递归的方式可以实现该算法。在实际编码中,可以利用哈希表来存储中序遍历结果中每个节点值对应的索引,以提高查找的效率。
重新开辟了多个数组导致空间复杂度O(N2), 传递数组下标位置再递归就不用另外开辟数组了
class Solution {& preorder, vector & inorder) {
unordered_map<int, int> valtoindex;
public:
TreeNode* buildTree(vector
for(int i=0; i<inorder.size(); i++){
valtoindex[inorder[i]] = i;
}
TreeNode* root = build(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
return root;
};
时间复杂度O(n),空间复杂度O(n)
复杂度
时间复杂度:$O(n)$
空间复杂度:$O(n)$
Code
思路:根据前序遍历和中序遍历的特性,找到其根节点位置,以及左右子树的范围,通过递归方法,逐步建立各个子树节点,完成对二叉树的重建
时间复杂度:O(n) 空间复杂度:O(n)
递归模拟
时间复杂度为O(n)
空间复杂度为O(n)
分治
看完讲解之后会写了,重点在于要把问题分解为子问题
时间复杂度:O(N)
空间复杂度:O(N) –这个不太清楚怎么得到的
没想出来,用官方代码
时间:O(n)
空间:O(n)
c++实现& inorder,int inorderBegin,int inorderEnd,vector & preorder,int preorderBegin,int preorderEnd)
private:
TreeNode* traversal(vector
{
if(preorderBeginpreorderEnd) return NULL;
int rootValue = preorder[preorderBegin];
TreeNode* root =new TreeNode(rootValue);
if(preorderEnd-preorderBegin1)return root;
public:& preorder, vector & inorder) {
TreeNode* buildTree(vector
if(preorder.size()0||inorder.size()0)return NULL;
return traversal(inorder,0,inorder.size(),preorder,0,preorder.size());
}
时间复杂度:O(n)
空间复杂度:O(n)
根据先序遍历确定根节点,根据中序遍历确定左右子树。
C++实现
时间复杂度O(n) 空间复杂度O(n)
前序遍历:中左右
中序遍历:左中右
根据前序遍历可以确定节点元素,以前序数组的第一个元素为切割点,先切中序数组,根据中序数组,反过来再切前序数组。一层一层切下去,每次前序数组的第一个元素就是节点元素。
时间复杂度:O(n)
空间复杂度:O(n)
C++实现:& preorder,int preBegin,int preEnd,vector & inorder,int inBegin,int inEnd)
class Solution {
public:
TreeNode* build(vector
{
if(preBegin preEnd) return NULL;
};
复杂度O(n) O(n)
复杂度O(n)
时空复杂度:O(n)
1、分析在根据前中序遍历建树的过程中,根据左右子树进行遍历,用到递归
2、确定递归函数的方法体参数,因为要在数组中进行,所以要设置,位置参数
MY用中序序列分左右子树