之前做过,参考16.树(5)中的最后一道题,用递归方式,将先序遍历的起始、结束下标,和中序遍历的起始、结束下标作为参数,在每个递归函数中先找到当前节点,即先序遍历的第一个节点,也就是中序遍历的某个中间节点,依据此节点将中序遍历一分为二,左边部分为当前节点的左子节点,右边部分为当前节点的右子节点,如此递归。
递归过程中要找到中间节点,如果每层递归中都用for循环来查找确定的话比较耗时,可以在一开始就用map保存每个val在inorder中的下标。
class Solution {
public:
unordered_map<int, int> indexs;
TreeNode* build(vector<int>& preorder, int beginPre, int endPre, vector<int>& inorder, int beginIn, int endIn) {
if (beginPre > endPre) {
return nullptr;
}
TreeNode* node = new TreeNode(preorder[beginPre]);
int mid = indexs[preorder[beginPre]];
int lenLeft = mid - beginIn, lenRight = endIn - mid;
node->left = build(preorder, beginPre + 1, beginPre + lenLeft, inorder, beginIn, beginIn + lenLeft - 1);
node->right = build(preorder, beginPre + lenLeft + 1, endPre, inorder, mid + 1, endIn);
return node;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n = preorder.size();
for (int i = 0; i < n; ++i) {
indexs[inorder[i]] = i;
}
return build(preorder, 0, n - 1, inorder, 0, n - 1);
}
};