题目链接:LeetCode 106 从中序与后序遍历序列构造二叉树
题目大意:
给定两个整数数组\(inorder\)和\(postorder\),其中\(inorder\)是二叉树的中序遍历,\(postorder\)是同一棵树的后序遍历,请你构造并返回这颗二叉树。
题解:
首先要知道,后序遍历的数组最后一个元素代表的即为根节点。知道这个性质后,我们可以利用已知的根节点信息在中序遍历的数组中找到根节点所在的下标,然后根据其将中序遍历的数组分成左右两部分,左边部分即左子树,右边部分为右子树,针对每个部分可以用同样的方法继续递归下去构造。
class Solution {
private:
int index;
unordered_map<int, int> indexMap;
public:
TreeNode* helper(int left, int right, vector<int>& inorder, vector<int>& postorder) {
// 如果这里没有节点构造二叉树了,就结束
if (left > right) {
return nullptr;
}
// 选择 index 位置的元素作为当前子树根节点
int rootVal = postorder[index];
TreeNode* root = new TreeNode(rootVal);
// 根据 root 所在位置分成左右两棵子树
int idx = indexMap[rootVal];
// 下标减一
index--;
// 构造右子树
root->right = helper(idx + 1, right, inorder, postorder);
// 构造左子树
root->left = helper(left, idx - 1, inorder, postorder);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
// 从后序遍历的最后一个元素开始
index = (int)postorder.size() - 1;
// 建立(元素,下标)键值对的哈希表
int idx = 0;
for (auto& val : inorder) {
indexMap[val] = idx++;
}
return helper(0, (int)inorder.size() - 1, inorder, postorder);
}
};