思路:
后续遍历的最后一个节点肯定是父亲节点, 然后回到中序遍历中,父亲节点的左边是左子树的所有节点,右边是右子树的所有节点,然后左子树和右子树根据之前的再找父亲 节点即可
代码如下:
/**
* 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:
map<int, int> mp;
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (inorder.empty()) return NULL;
for (int i = 0; i < inorder.size(); i++) mp[inorder[i]] = i; //记住每个数的位置
return build(inorder, postorder, 0, inorder.size() - 1, 0, postorder.size() - 1);
}
TreeNode * build(vector<int>& inorder, vector<int>& postorder, int inL, int inR, int pL, int pR){
if (pL > pR) return NULL;
//后序遍历的最后一个节点是根节点
TreeNode * root = new TreeNode(postorder[pR]);
//在中序遍历中找到根节点的序号,将中序遍历分成左子树、右子树两部分
int k = mp[postorder[pR]];
//构建左子树,中序遍历中的前k-1个和先序遍历中的前k-1个
root->left = build(inorder, postorder, inL, k - 1, pL, pL + k - inL - 1);
//构建右子树,除了左子树中的元素以及根节点的元素
root->right = build(inorder, postorder, k + 1, inR, pL + k - inL, pR - 1);
return root;
}
};