题目:
Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
思路:
后序遍历结果的最后一个值就是树的根结点
根结点的左子树的根结点就是它的左孩子,根结点的右子树的根结点就是它的右孩子,只要找到左子树和右子树即可确定当前结点的左右孩子。
在中序遍历结果中,可知根结点的前面的元素即是它的左子树的元素,根结点的后面的元素即是它的右子树的元素。
在后序遍历结果中,根结点位于最后,把前面的元素分成两部分,则前一部分是左子树的元素,后一部分是右子树的元素,如何确定左子树元素到哪里是关键。这里可以通过在中序遍历结果中左子树中的元素的个数定位在后序遍历中前一部分到哪里,具体实现看代码。
代码:
/**
* 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)
{
if(inorder.empty() || postorder.empty())
return NULL;
return createTree(inorder,0,inorder.size()-1,postorder,0,postorder.size()-1);
}
TreeNode *createTree(vector<int> &inorder,int inBeg,int inEnd, vector<int> &postorder,int postBeg,int postEnd)
{
if(inBeg > inEnd)
return NULL;
TreeNode *root = new TreeNode(postorder[postEnd]);//后序遍历的最后一个值是当前的根结点
int i = inBeg ;
//在中序遍历的结果中定位到根结点的的位置,则这个位置前面的元素是根结点的左子树的元素,后面的元素是跟结点右子树的元素
while(i < inEnd && inorder[i] != postorder[postEnd])
{
i++;
}
int len = i - inBeg;//len是左子树中的元素个数,因此在后续遍历的结果中,前一部分是从postBeg到postBeg+len-1
//根结点的左孩子是左子树的根结点,左子树的元素在中序遍历结果中的下标是inBeg到i-1,在后续遍历结果中的下标是postBeg到postBeg+len-1
root->left = createTree(inorder,inBeg,i-1,postorder,postBeg,postBeg+len-1);
//根结点的右孩子是右子树的根结点,右子树的元素在中序遍历结果中的下标是i+1到inEnd,在后续遍历结果中的下标是postBeg+len,postEnd-1
root->right = createTree(inorder,i+1,inEnd,postorder,postBeg+len,postEnd-1);
return root;
}
};