重点:
(1)递归:重点是找到分割对应的左右子树;
难度中等
给定两个整数数组 preorder
和 inorder
,其中 preorder
是二叉树的先序遍历, inorder
是同一棵树的中序遍历,请构造二叉树并返回其根节点。
示例 1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] 输出: [3,9,20,null,null,15,7]
示例 2:
输入: preorder = [-1], inorder = [-1] 输出: [-1]
提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder
和inorder
均 无重复 元素inorder
均出现在preorder
preorder
保证 为二叉树的前序遍历序列inorder
保证 为二叉树的中序遍历序列
解析:
掌握由前序遍历和中序遍历得到二叉树的方法。
对于任意一棵树而言,前序遍历的形式总是:
[ 根节点,[左子树的前序遍历结果],[右子树的前序遍历结果] ]
即根节点总是前序遍历中的第一个节点。而中序遍历的形式总是
[ [左子树的中序遍历结果],根节点,[右子树的中序遍历结果] ]
我们只需要在中序遍历中定位到根节点,那么可以知道其左右子树的节点数目,同时对左右括号进行定位。然后递归的构造出左子树和右子树,再将两颗子树接到根节点的左右位置。
代码:
class Solution {
private:
map<int,int> mymap;
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n=preorder.size();
for(int i=0;i<n;i++)
mymap[inorder[i]]=i;
return dfs(preorder,inorder,0,n-1,0,n-1);
}
TreeNode* dfs(vector<int>& pre, vector<int>& in,int s1,int e1,int s2,int e2){
if(s1>e1)
return nullptr;
TreeNode *root=new TreeNode(pre[s1]);
int index=mymap[pre[s1]];
int in1left=s2;
int in1right=index-1;
int in2left=index+1;
int in2right=e2;
int pre1left=s1+1;
int pre1right=pre1left+(in1right-in1left);
int pre2left=pre1right+1;
int pre2right=e1;
root->left=dfs(pre,in,pre1left,pre1right,in1left,in1right);
root->right=dfs(pre,in,pre2left,pre2right,in2left,in2right);
return root;
}
};