题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
示例:
前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7]
结果
3
/
9 20
/
15 7
题解:
二叉树前序遍历的顺序为:
先遍历根节点;随后递归地遍历左子树;最后递归地遍历右子树。
二叉树中序遍历的顺序为:
先递归地遍历左子树;随后遍历根节点;最后递归地遍历右子树。
根据前序遍历和中序遍历我们知道。前序数组的一位是根节点,而此时我们再看中序遍历,可以的知,根节点的前面部分就是根节点的左子树,有半部分值其根节点的右子树,当我们求出根节点在中序遍历数组中的位置时,
既可以确定左子树有多少,右子树有多少,因此我们就可以对其中序数组和前序数组进行切割,将大的问题变为小的问题。一下就是本题的详细代码。
class Solution(object):
def buildTree(self, preorder, inorder):
if len(inorder) == 0:
return None
root = TreeNode(preorder[0])
mid = inorder.index(root.val)
root.left = self.buildTree(preorder[1 : mid + 1], inorder[:mid])
root.right = self.buildTree(preorder[mid+ 1:], inorder[mid + 1:])
return root
/**
* 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 {
private:
unordered_map<int, int> index;
public:
TreeNode* bulidTreeSet(const vector<int>& preorder, const vector<int>& inorder, int pre_left, int pre_right,int ind_left, int ind_right)
{
if(pre_left > pre_right)
{
return NULL;
}
int pre_root = pre_left;
int ind_root = index[preorder[pre_root]];
TreeNode* root = new TreeNode(preorder[pre_root]);
int size_left_sub = ind_root - ind_left;
root->left = bulidTreeSet(preorder,inorder,pre_left + 1, pre_left+ size_left_sub,ind_left,ind_root - 1);
root->right = bulidTreeSet(preorder,inorder,pre_left + size_left_sub + 1,pre_right, ind_root + 1, ind_right);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n = preorder.size();
for(int i = 0; i<n;i++)
{
//构造下标,便于查找元素的下标
index[inorder[i]] = i;
}
return bulidTreeSet(preorder, inorder, 0, n - 1,0, n -1);
}
};