解题思路:
1.以根节点为例子,根据后序数组的特点,我们可以从后序数组找到根节点,此时我们无法判别后序数组那一部分是根节点的左子树,那一部分是右子树的。而中序可以在利用后序数组中根节点基础上推出根节点的左右两个子节点,然后根据以这个值为界限切割,中序数组,这样我们就得到了在根节点下的左子树和右子树。
2.可接下来又遇到了一个问题,根节点的左子树和右子树的第一个节点该怎么确定呢,回到前面我们是通过后序数组来确定根节点的,所以同样的我们也需要利用后序数组的左子树部分最后一个元素,和后序数组右子树部分的最后一个元素来确定第一个节点
3.所以接下来我们需要切割后序数组,得到后序数组的左子树部分和右子树部分,利用下面这个注意条件我们就可以切割
注意:无论是后序还是中序,数组储存的左子树和右字数大小一定是一样的,只是数组元素排序因遍历顺序而改变
下面是代码实现部分:
class Solution {
TreeNode* f(vector<int>& inorder, vector<int>& postorder)
{
if(postorder.size()==0)
return NULL;
int rootval=postorder[postorder.size()-1];
//这里是赋值操作
TreeNode* root=new TreeNode(rootval);
//这里是代表遇到了叶子节点,开始返回
if(postorder.size()==1)
return root;
int index;
//利用rootval所代表的节点遍历前序数组找到切割节点位置
for(index=0;index<inorder.size();index++)
{
if(inorder[index]==rootval)
break;
}
//切割中序数组,注意切割区间
vector<int>midrigt(inorder.begin()+index+1,inorder.end());
vector<int>midleft(inorder.begin(),inorder.begin()+index);
//切割后序数组,注意切割区间
postorder.resize(postorder.size() - 1);
vector<int>afterleft(postorder.begin(),postorder.begin()+midleft.size());
vector<int>afterrigt(postorder.begin()+midleft.size(),postorder.end());
//进行下一次的递归
root->left=buildTree(midleft,afterleft);
root->right=buildTree(midrigt,afterrigt);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
{
if(inorder.size()==0||postorder.size()==0)
return NULL;
return f(inorder,postorder);
}
};