1、描述
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
链接
2、关键字
二叉树,重建,前序和中序,没有重复的数字,
3、思路
1、根据前序知道第一个元素是根,
2、根据根节点去中序遍历序列中分出左右子树,
3、根据第2步中分出的两部分,再看前序遍历寻找左右子树的根节点,
形成递归
把前序遍历搞成自己内部的重开一个vector,把中序遍历搞成一个字典,方便记录递归时候的左右两端的界限。
递归函数recur 的3个参数分别是 前序遍历中:根节点的下标,左边界,右边界
构造树,是通过根左右的方式构造的,递归构造的,先序遍历
4、notes
1、没思路,时候,记下这个就把前序搞成私有复制一下,把中序遍历搞成字典,遍历一遍,把中序遍历的元素和他的下标搞成映射关系,
5、复杂度
时间:O(N),N是树的节点个数,
空间:O(N)
6、code
/**
* 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 {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
this->preorder = preorder; // 把前序遍历存起来
for( int i = 0; i < inorder.size() ; i++){ // 把中序遍历构成hash映射,元素到下标的映射
dic[inorder[i]] = i;
}
return recur(0, 0, inorder.size() - 1); // 递归函数
}
private:
vector<int> preorder; // 存成自己的
unordered_map<int,int> dic;
TreeNode * recur(int root_ind,int left,int right){ // 前序遍历中 根节点的下标,左边界,右边界
if(left > right) return nullptr; // 如果左边界大于右边界,退出
TreeNode * node = new TreeNode(preorder[root_ind]); // 1、根据前序遍历 构造根节点,
int i = dic[preorder[root_ind]]; // 2、去hash中寻找根节点对应的下标,分段
node->left = recur(root_ind + 1,left, i - 1); // 3、左边一段:根节点,左边界,右边界
node->right = recur(root_ind + (i - left) + 1,i + 1,right); // 右边一段:根节点=上一层的根节点+(左一段的长度),左边界,右边界,
return node;
}
};