題目
返回與給定的前序和后序遍歷匹配的任何二叉樹(shù)菇夸。
pre
和 post
遍歷中的值是不同的正整數(shù)。
示例
輸入:pre = [1,2,4,5,3,6,7], post = [4,5,2,6,7,3,1]
輸出:[1,2,3,4,5,6,7]
提示:
1 <= pre.length == post.length <= 30
-
pre[] 和 post[] 都是 1, 2, ..., pre.length
的排列 - 每個(gè)輸入保證至少有一個(gè)答案贰谣。如果有多個(gè)答案胀葱,可以返回其中一個(gè)誓禁。
題目分析
這道題要求我們根據(jù)前序遍歷和后序遍歷構(gòu)造二叉樹(shù)雅任。已知前序遍歷的順序是ulr辽幌,后序遍歷的順序是lru,所以前序遍歷的第一個(gè)元素是根節(jié)點(diǎn)椿访,后序遍歷的最后一個(gè)元素也是根節(jié)點(diǎn)。
刨除根節(jié)點(diǎn)后虑润,剩余序列均由l+r的順序組成成玫,我們只需要知道l或r的元素個(gè)數(shù),就可以采用分治法遞歸的構(gòu)建樹(shù)拳喻。
以示例為例哭当,我們簡(jiǎn)單分析一下這個(gè)過(guò)程,通過(guò)前序序列冗澈,我們可以知道左子樹(shù)的頭結(jié)點(diǎn)是2钦勘,我們可以在后序遍歷序列中找到2,2之前的就是左子樹(shù)亚亲,2之后的就是右子樹(shù)彻采。這樣我們就可以確定左右子樹(shù)的數(shù)量,可以分塊進(jìn)行建樹(shù)操作了捌归。
TreeNode* creTree(vector<int> pre, int prel, int prer, vector<int> post, int postl, int postr){
if (prel > prer || postl > postr) return NULL;
TreeNode* root = new TreeNode(pre[prel]);
if (prel == prer) return root;
int idx = 0;
while (pre[prel + 1] != post[idx]) idx++;
root->left = creTree(pre, prel + 1, idx - postl + prel + 1, post, postl, idx);
root->right = creTree(pre, idx - postl + prel + 2, prer, post, idx + 1, postr - 1);
return root;
}
題目解答
class Solution {
public:
TreeNode* creTree(vector<int> pre, int prel, int prer, vector<int> post, int postl, int postr){
if (prel > prer || postl > postr) return NULL;
TreeNode* root = new TreeNode(pre[prel]);
if (prel == prer) return root;
int idx = 0;
while (pre[prel + 1] != post[idx]) idx++;
root->left = creTree(pre, prel + 1, idx - postl + prel + 1, post, postl, idx);
root->right = creTree(pre, idx - postl + prel + 2, prer, post, idx + 1, postr - 1);
return root;
}
TreeNode* constructFromPrePost(vector<int>& pre, vector<int>& post) {
return creTree(pre, 0, pre.size() - 1, post, 0, post.size() - 1);
}
};