题目描述:输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
示例 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] Output: [3,9,20,null,null,15,7]
示例 2:
Input: preorder = [-1], inorder = [-1] Output: [-1]
解题思路:
根据前序遍历和中序遍历的特点,前序遍历的第一个节点就是根,在中序遍历中找到根的位置,左边是根的左子树,右边是根的右子树。
接下来根据找到的中序遍历的左子树的个数,找到在前序遍历中的左子树。其中前序遍历中的左子树是左子树的前序遍历;而中序遍历中的左子树是左子树的中序遍历。右子树同理,根据这一性质递归求解二叉树。其过程如下图:
获取中序遍历根节点位置的方法是创建一个哈希表,依次遍历中序结构,将值和位置对应到哈希表中。递归结束条件:子树个数为0
/**
* 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>pos;
public:
TreeNode* myBuildTree(vector<int>&preorder, vector<int>&inorder, int l1, int r1, int l2, int r2){
if(l1>r1&&l2>r2){
return nullptr;
}
int i=pos[preorder[l1]];
TreeNode* root = new TreeNode(preorder[l1]);
root->left = myBuildTree(preorder, inorder, l1+1, l1+(i-l2), l2, i-1);
root->right=myBuildTree(preorder, inorder, l1+(i-l2)+1, r1, i+1, r2);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int sum = preorder.size();
for(int i=0; i<sum; ++i){
pos[inorder[i]]=i;
}
return myBuildTree(preorder, inorder, 0, sum-1, 0, sum-1);
}
};