Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
For example, given
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
Return the following binary tree:
3
/ \
9 20
/ \
15 7
记得考研的时候学习数据结构,经常会遇到根据某两种序列求另一种序列,当然并非已知两种遍历序列都可以求解第三种遍历序列。我们先分析下手动求解中序序列的方法:
例子:
preorder 前序 {3,9,20,15,7}
inorder 中序 {9,3,15,20,7}
前序中第一个元素3,因此在后续中3之前的数据为3的左孩子(此例中只有结点9,因此根结点的左孩子是9),3之后的是其右孩子,接下来在前序遍历中找到20,此时后续遍历中仅剩15 20 7,可以判定15是20的左结点,7是20的右结点。因此二叉树结构如下:
3
/ \
9 20
/ \
15 7
/**
* 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)
{
int rootInex = 0;
return helper(preorder, rootInex, inorder, 0, inorder.size() - 1);
}
private:
TreeNode* helper(vector<int>& preorder, int& rootIndex, vector<int>& inorder, int start, int end)
{
if(rootIndex >= preorder.size() || start > end)
return nullptr;
// tree [3,9,20,null,null,15,7]
// preorder [3,9,20,15,7]
// inorder [9,3,15,20,7]
// 每次从 preorder 头部取一个值 preorder[rootIndex],作为树的根节点
// 检查 preorder[rootIndex] 在 inorder 中 的位置,则preorder[rootIndex]前面部分将作为树的左子树,右部分作为树的右子树
TreeNode* root = new TreeNode(preorder[rootIndex]);
auto pos = distance(inorder.begin(), find(inorder.begin() + start , inorder.begin() + end,preorder[rootIndex++]));
root->left = helper(preorder, rootIndex, inorder, start, pos - 1);
root->right = helper(preorder, rootIndex, inorder, pos + 1, end);
return root;
}
};
inorder 是中序
@123 感谢指正,已更正