题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
限制:
0 <= 节点个数 <= 5000
递归
本题直接利用的是二叉树先序遍历和中序遍历的特点,通过递归来求解出答案。
1、通过先序遍历,拿到第一个节点,即为二叉树根节点;
2、利用该根节点,算出左子树节点数量,右子树节点数量;
3、利用数量和根节点在中序节点中遍历,分别算出当前二叉树左右子树的对应先序遍历列表和中序遍历列表;
4、递归求解;
/**
* 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:
map<int, int> dis; //巧妙借助了map,提高检索性能,缩短时间
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
for(int i = 0; i < inorder.size(); i++){
dis[inorder[i]] = i;
}
return dfs(preorder, 0, preorder.size(), inorder, 0, inorder.size());
}
TreeNode* dfs(vector<int>& preorder, int preBegin, int preEnd, vector<int>& inorder, int inBegin, int inEnd){
if(preBegin >= preEnd || inBegin >= inEnd){
return nullptr;
}
TreeNode* root = new TreeNode(preorder[preBegin]);
int index = dis[preorder[preBegin]];
root->left = dfs(preorder, preBegin+1, preBegin+1+(index-inBegin), inorder, inBegin, index);
root->right = dfs(preorder, preBegin+1+(index-inBegin), preEnd, inorder, index+1, inEnd);
return root;
}
};