题目描述
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
解题思路
-
首先,根据前序遍历结果确定根节点。前序遍历的第一个元素即为根节点的值。
-
接下来,在中序遍历中找到根节点的位置,根节点左侧的元素为左子树的中序遍历结果,右侧的元素为右子树的中序遍历结果。
-
递归构建左子树和右子树,重复上述步骤。
-
返回根节点。
这个算法的时间复杂度是 O(n),其中 n 是二叉树中的节点数,因为我们每个节点都只访问一次。空间复杂度也是 O(n),因为我们需要递归调用来构建子树,同时需要存储中序遍历的结果。
下面的代码中用到了`unordered_map`是为了更好的找到中序访问的下标。
代码及结果
TreeNode* Solution::buildTree(std::vector<int>& preorder, std::vector<int>& inorder)
{std::unordered_map<int, int> inorder_map;for (int i = 0; i < inorder.size(); ++i) {inorder_map[inorder[i]] = i;}int pre_index = 0;return build(preorder, inorder, 0, inorder.size() - 1, pre_index, inorder_map);
}TreeNode* Solution::build(std::vector<int>& preorder, std::vector<int>& inorder, int in_start, int in_end, int& pre_index, std::unordered_map<int, int>& inorder_map)
{if (in_start > in_end) {return nullptr;}int root_val = preorder[pre_index++];TreeNode* root = new TreeNode(root_val);int in_index = inorder_map[root_val];root->left = build(preorder, inorder, in_start, in_index - 1, pre_index, inorder_map);root->right = build(preorder, inorder, in_index + 1, in_end, pre_index, inorder_map);return root;
}