根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
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>& inorder, vector<int>& postorder) {
return pre_order(0, inorder.size() - 1, 0, inorder.size() - 1, inorder, postorder);
}
TreeNode *pre_order(int leftin, int rightin, int leftpost, int rightpost, vector<int> &in, vector<int> &post) {
if (leftin > rightin){
return NULL;
}
// 后序的最右边的点一定是根
TreeNode *root = new TreeNode(post[rightpost]);
int rootin = leftin;
// 查找根节点的位置
while (rootin <= rightin && in[rootin] != post[rightpost]){
rootin++;
}
//左子树的个数
int left = rootin - leftin;
// 通过左子树的范围进行构建
root->left = pre_order(leftin, rootin - 1, leftpost, leftpost + left - 1, in, post);
// 通过右子树的范围进行构建
root->right = pre_order(rootin + 1, rightin, leftpost + left, rightpost - 1, in, post);
return root;
}
};