刷题记录-剑指 Offer 07. 重建二叉树

https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

tree.jpg

示例:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
限制:
0 <= 节点个数 <= 5000

使用分治思想,递归得到结果

1,先由前序数组得到根节点,在中序数组中找到根节点对应位置,判断左子树和右子树的长度。
2,将左子树和右子树重新当成新树,迭代步骤1.

递归:

1、传递参数:左子树 的前序中序在原树中的位置 pre_l,pre_r;右子树 的前序中序在原树中的位置 in_l,in_r;
2、终止条件:if(pre_l>pre_r ||in_l>in_r) return NULL;
3、基本操作:
新建根节点 TreeNode *root=new TreeNode(preorder[pre_l])
连接左孩子root->left=buildTreeHelper(preorder,inorder,pre_l+1,pre_l+k-in_l,in_l,k-1);
连接右孩子 root->right=buildTreeHelper(preorder,inorder,pre_l+k-in_l+1,pre_r,k+1,in_r);
4、返回根节点root

class Solution {
public:
    unordered_map map;
    TreeNode* buildTree(vector& preorder, vector& inorder) {
        if(preorder.empty() || inorder.empty()) return NULL;
        int len=preorder.size();
        for(int i=0;i<=len-1;i++){
            map[inorder[i]]=i;
        }
        return buildTreeHelper(preorder,inorder,0,len-1,0,len-1);

    }
    
    TreeNode* buildTreeHelper(vector& preorder, vector& inorder,int pre_l,int pre_r,int in_l, int in_r){
        if(pre_l>pre_r ||in_l>in_r) return NULL;
        TreeNode* root=new TreeNode(preorder[pre_l]);
        //遍历inorder 找根节点
        // int k=0;
        // for(int i=in_l;i<=in_r;i++){
        //     if(preorder[pre_l]==inorder[i]) 
        //         k=i;
        // }
        //直接map找根节点位置
        int k=map[preorder[pre_l]];
        
        root->left=buildTreeHelper(preorder,inorder,pre_l+1,pre_l+k-in_l,in_l,k-1);
        root->right=buildTreeHelper(preorder,inorder,pre_l+k-in_l+1,pre_r,k+1,in_r);
        return root;
    }    
};

其中在中序数组inorder[] 遍历找根节点(时间复杂度O(n))可以采用哈希map(O(1))实现.

复杂度分析:

时间复杂度:O(N), 其中 N 为树的节点数量。初始化 HashMap 需遍历 inorder ,占用 O(N) 。递归共建立 N个节点,每层递归中的节点建立、搜索操作占用 O(1) ,因此使用 O(N) 时间。

空间复杂度:O(n),除去返回的答案需要的 O(N) 空间之外,我们还需要使用 O(N) 的空间存储哈希映射,以及 O(H)(其中 h 是树的高度)的空间表示递归时栈空间。这里 h < n,所以总空间复杂度为 O(N)。

你可能感兴趣的:(刷题记录-剑指 Offer 07. 重建二叉树)