105. Construct Binary Tree from Preorder and Inorder Traversal

来源:互联网 发布:淘宝网儿童足球鞋 编辑:程序博客网 时间:2024/05/24 03:23

题目

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

思路

这道题目,翻译一下就是:如何根据先序和中序遍历的数组,来构造二叉树。其中Note部分说,假设不存在重复项。为什么这样说呢?因为如果存在重复项,那么构造出来的树就不是唯一的。
比如说数组{7,7}就有两种树形结构:

  7                     7 /           or          \7                         7

那么接下来我们来举个例子:存在先序遍历数组、中序遍历数组如下所示:

preorder = {7,10,4,3,1,2,8,11}inorder = {4,10,3,1,7,11,8,2}

观察数组构造,我们会发现中序遍历中的根节点必然是先序遍历的第一个元素。我们根据先序遍历中的第一个元素7找到根节点,然后在中序遍历数组中找到7的索引是4,然后我们发现索引4的左边是左子树,右边是右子树。然后我们继续根据左子树的根节点10找到中虚遍历中的索引位置1,然后又发现了索引1的左边{1}是左子树,索引1的右边{3,1}是右子树。这样我们就能用递归的方法构造出对应的二叉树。

在上述思路中,我们根据先序遍历数组里的根节点找到中序遍历数组里的索引,这个索引的查找,如果是顺序查找,最长时间复杂度是O(n),如果该树是平衡二叉树,那么平均时间复杂度是O(logn)

因此为了缩减构造树的时间复杂度,我们可以通过建立哈希表,这样查找索引的时间就是O(1)。因此构造二叉树的时间就是O(N),线性时间复杂度!

代码

/** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {        //step1:construct hash-tab        if(preorder.size()==0)            return NULL;        unordered_map<int,int> mapIndex;        for(int i=0;i<inorder.size();i++)            mapIndex[inorder[i]] = i;        return helpTree(preorder,0,inorder.size(),0,mapIndex);    }private:    TreeNode* helpTree(vector<int>& preorder,int start,int len,int offest,unordered_map<int,int>& mapIndex)    {        if(len<=0)            return NULL;        int rootval = preorder[start];//vist root         int i = mapIndex[rootval]-offest;//compute len of left tree        TreeNode* root = new TreeNode(rootval);        start++;        root->left = helpTree(preorder,start,i,offest,mapIndex);//construct left subtree        root->right = helpTree(preorder,start+i,len-i-1,offest+i+1,mapIndex);//construct right subtree        return root;    }};
阅读全文
1 0
原创粉丝点击