难度中等930
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。例如,给出
前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7]返回如下的二叉树:
3 / \ 9 20 / \ 15 7
思路解析:
主要思路是这样的,中序遍历可以得到一个树的根节点,再通过前序遍历和根节点可以知道这棵树的左子树和右子树中的节点个数,再不断进行递归操作,能够构造出左子树和右子树,最后接到根节点上去,即形成一棵二叉树。
需要注意的是映射位置,也就是对根节点定位,可以看成每个子树的根节点定位。官方给出题解的做法是,将中序遍历的序列放到哈希表里面去,能够快速帮助找到根节点。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
unordered_map<int, int> index;
TreeNode* myBuildTree(const vector<int>& preorder, const vector<int>& inorder, int pre_left, int pre_right, int in_left, int in_right){
if (pre_left > pre_right){
return nullptr;
}
int pre_root = pre_left;//前序遍历中根节点位置
int in_root = index[preorder[pre_root]];//中序遍历中根节点位置
TreeNode* root = new TreeNode(preorder[pre_root]);
int size_left_subTree = in_root - in_left; //两位置只差为左子树节点个数
root->left = myBuildTree(preorder, inorder, pre_left+1, pre_left+ size_left_subTree, in_left, in_root-1);
root->right = myBuildTree(preorder, inorder, pre_left+size_left_subTree+1, pre_right, in_root+1, in_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 myBuildTree(preorder, inorder, 0, n-1, 0, n-1);
}
};
后话:
时隔很久,现在又开始继续算法练习了,加油啊!