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 a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
解答:
题目要求通过中序(左、根、右)和后序(左、右、根)重建一棵二叉树,例如
/*
例:
1
/ \
2 3
/\
4 5
后序:4 5 2 3 1
中序:4 2 5 1 3
*/
构建的方法其实很简单:后序的最后一个元素是根,在中序中找到它,那么按照中序的特点,这个元素左边的就是左子树,右边的就是右子树,这样递归做下去就可以了。
代码:
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return dfs(inorder,postorder,0,inorder.size()-1,0,postorder.size()-1);
}
TreeNode* dfs(vector<int>& inorder,vector<int>& postorder,int is,int ie,int ps,int pe){
if(is>ie)
return nullptr;
TreeNode* root=new TreeNode(postorder[pe]);
int pos;
for(int i=is;i<=ie;i++){
if(inorder[i]==root->val){
pos=i;
break;
}
}
root->left=dfs(inorder,postorder,is,pos-1,ps,ps+pos-is-1);//because pe-ps=pos-1-is (the number of the rest elements should be equal)
root->right=dfs(inorder,postorder,pos+1,ie,pe-ie+pos,pe-1);//pe-1-ps=ie-(pos+1) => ps=pe-ie+pos
return root;
}
};
说起来。。有想法和能把想法转换成代码这之间是有一定差距的。。。还有,看了别人的代码就“懂”了,自己写却不会,这是最悲伤的quq
这个问题还有非递归的解法,代码来自Discuss:
using namespace std;
#define forLess(i, s, e) for(int i = (s); i < int(e); ++i)
#define forto(i, s, e) for(int i = (s); i <= int(e); ++i)
class Solution
{
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
{
TreeNode* cur = NULL;
int i = 0, j = 0;
stack<TreeNode *> s;
while(i < inorder.size() && j < postorder.size()){
if(inorder[i] == postorder[j]){
TreeNode *t = new TreeNode(inorder[i]);
t->left = cur;
cur = t;
i++;
j++;
}
else{
if(!s.empty() && postorder[j] == s.top()->val){
TreeNode *t = s.top();
s.pop();
t->right = cur;
cur = t;
j++;
}
else{
TreeNode *t = new TreeNode(inorder[i]);
t->left = cur;
cur = NULL;
s.push(t);
i++;
}
}
}
while(!s.empty()){
TreeNode *t = s.top();
s.pop();
t->right = cur;
cur = t;
}
return cur;
}
};