【题目】
Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
【题意】
根据中序和后序遍历结果构建二叉树
【分析】
找到根节点在中序遍历中的index,由于元素不重复,通过根可以讲中序遍历inorder划分为左子树和右子树。然后递归就好,难点在于子序列初始位置的计算
/ \ 2 3 / \ / \ 4 5 6 7对于上图的树来说, index: 0 1 2 3 4 5 6 中序遍历为: 4 2 5 1 6 3 7 后续遍历为: 4 5 2 6 7 3 11. 中序遍历中根节点是左子树右子树的分割点。2. 后续遍历的最后一个节点为根节点。同样根据中序遍历找到根节点的位置,然后顺势计算出左子树串的长度。在后序遍历中分割出左子树串和右子树串,递归的建立左子树和右子树。
【实现】
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) { return Helper(inorder, 0, inorder.size()-1, postorder, 0, postorder.size()-1); } TreeNode* Helper(vector<int>& inorder, int begin1, int end1, vector<int>& postorder, int begin2, int end2) { if(begin1 > end1) return NULL; else if(begin1 == end1) return new TreeNode(inorder[begin1]); TreeNode* root = new TreeNode(postorder[end2]); int i = begin1; for(; i <= end1; i ++) { if(inorder[i] == postorder[end2]) break; } int leftlen = i-begin1; root->left = Helper(inorder, begin1, begin1+leftlen-1, postorder, begin2, begin2+leftlen-1); root->right = Helper(inorder, begin1+leftlen+1, end1, postorder, begin2+leftlen, end2-1); return root; } };
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) { // Start typing your C/C++ solution below // DO NOT write int main() function return build(inorder, postorder, 0, 0, inorder.size()); } TreeNode * build(vector<int> &inorder, vector<int> &postorder, int posp, int posi, int len){ if(len <= 0){return NULL;} int root_val = postorder[posp + len -1]; TreeNode * root = new TreeNode(root_val); int root_index = 0; for(int i = posi ; i < posi + len; ++i){ if(inorder[i] == root_val){ root_index = i; break; } } root->left = build(inorder, postorder, posp, posi, root_index - posi); root->right = build(inorder, postorder, posp + root_index - posi, root_index + 1, len + posi - root_index - 1); return root; } };