题目
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
样例:
-
还是老样子想自己思考一下, 想一想前序遍历和后序遍历的关系如果搞清这个后面就好搞, 另外会了这道题那么知道后序遍历和中序遍历建二叉树, 一样的道理, 可以试着写一些。
-
思路:
- 我们来想先序遍历是不是根每次最先被遍历, 那面先序遍历的结果的第一个永远是本颗树的根节点,
- 中序遍历呢, 他根节点是 在遍历完左子树 之后遍历根在遍历右子树, 那么知道根的位置 , 就可以在中序遍历里面把 遍历结果分为左子树和右子树的遍历结果。
- 那么这道题就可以递归求解 返回本节点的左右子树
class Solution {
public:
unordered_map<int,int> in; //这个是用来存中序遍历每个值在原数组的位置, 以o(1)的时间定位根节点的位置
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.size() == 0) return NULL;
for (int i = 0; i < inorder.size(); i ++)
in[inorder[i]] = i;
return build(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
}
//pl 是前序遍历的左指针 pr 是前序遍历的右指针, il是中序遍历的左指针 ir是中序遍历的右指针
TreeNode* build(vector<int> preorder, vector<int> inorder, int pl, int pr, int il, int ir){
// if (pl == pr){
// return new TreeNode(preorder[pl]);
// }
TreeNode* head = new TreeNode(preorder[pl]); //当前根节点
int t = in[preorder[pl]]; //根节点在中序遍历的位置
if (il < t) head -> left = build(preorder, inorder, pl + 1, pl + t + 1 - il, il, t - 1); //向左递归得到左子树 这里pr是这样
//来得到的因为左子树的个数可以用根节点的位置和ir指针得到, 那么在前序遍历中左子树的大小也是这样所有就是pl + l.size();右子树同样
if (ir > t) head -> right = build (preorder, inorder, pl + t + 2 - il, pr, t + 1, ir); //向右递归得到右子树
return head;
}
};
大家可以思考以下后序遍历和中序遍历的做法