原题链接
思路:
- 根据前序遍历和后续遍历的原理,对数组进行划分,使用递归结构解决构建树的问题。
- 前序遍历的第一个元素是该数组构成树的根节点,在中序遍历中找到该元素,左边即为该根节点的左子树,右边为该根节点的右子树。
- 记录中序序列中左子树节点数,在前序序列中根据该数目得到左子树的前序序列和右子树序列。在中序序列中得到左子树的中序序列和右子树的中序序列。
- 对这两部分使用递归。
- 递归边界是子树为空。
- 树中不能有重复数字节点,不然会影响找根节点位置。
给出代码:
/**
* 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) {
if(preorder.empty()) return NULL;
TreeNode * root = new TreeNode(preorder[0]);
int i = 0;
// 去找根节点在中序遍历中的位置,该位置之前的就是左子树的节点
// 右边是右子树的节点
while(inorder[i] != preorder[0]){
i++;
}
// 分别得到左子树的前序中序遍历数组,右子树的前序中序遍历数组
vector<int> leftPreOrder(preorder.begin()+1,preorder.begin()+1+i);
vector<int> leftInOrder(inorder.begin(), inorder.begin()+i);
vector<int> rightPreOrder(preorder.begin()+1+i,preorder.end());
vector<int> rightInOrder(inorder.begin()+1+i,inorder.end());
// 对左右子树递归
root->left = buildTree(leftPreOrder,leftInOrder);
root->right = buildTree(rightPreOrder,rightInOrder);
return root;
}
};