样例
给出中序遍历:[1,2,3]
和前序遍历:[2,1,3]
. 返回如下的树:
2
/ \
1 3
树节点数据结构
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
注意
输出为一棵树。
你可以假设树中不存在相同数值的节点
可在LintCode网页上编写本题代码:
前序遍历和中序遍历树构造二叉树
分析
题目中输入为
vector<int> &preorder; //先序序列
vector<int> &inorder; //中序序列
输出为一棵树。
输入输出见一下:
class Solution {
/**
*@param preorder : A list of integers that preorder traversal of a tree
*@param inorder : A list of integers that inorder traversal of a tree
*@return : Root of a tree
*/
public:
TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
// write your code here
}
};
- 考虑到先序是先访问根节点,故先序的第一个节点preorder[0]为整棵树的根节点。
- 题中已假设每个节点之间数值不等,因而在确定根节点数值root->val之后,可以通过该值来确定左子树和右子树的范围。
- 中序遍历inorder中,root->val之前出现的节点为左子树包含的节点,root->val之后出现的节点为右子树包含的节点。
- 明确左子树节点和右子树节点之后,可以递归调用函数了。
程序代码
class Solution {
/**
*@param preorder : A list of integers that preorder traversal of a tree
*@param inorder : A list of integers that inorder traversal of a tree
*@return : Root of a tree
*/
public:
TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
// write your code here
if(!preorder.size() || !inorder.size() || preorder.size()!=inorder.size())
return NULL;
if(preorder.size()==1)
return new TreeNode(preorder[0]);
//划分子树
vector<int> sub_preorder1; //左子树先序
vector<int> sub_preorder2; //右子树先序
vector<int> sub_inorder1; //左子树中序
vector<int> sub_inorder2; //右子树中序
int i;
for(i=0; inorder[i]!=preorder[0]; i++){
sub_inorder1.push_back(inorder[i]);
}
for(++i; i<inorder.size(); i++){
sub_inorder2.push_back(inorder[i]);
}
int j;
for(j=0; j<sub_inorder1.size(); j++){
sub_preorder1.push_back(preorder[j+1]);
}
for(; j<preorder.size()-1; j++){
sub_preorder2.push_back(preorder[j+1]);
}
//递归
TreeNode* root = new TreeNode(preorder[0]);
root->left = buildTree(sub_preorder1, sub_inorder1);
root->right = buildTree(sub_preorder2, sub_inorder2);
return root;
}
};