前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
根据不同遍历方式返回如下二叉树:
3
/ \
9 20
/ \
15 7
表示:
index:用来寻找并表示左右子树分开的节点。
pre:前序数组
preStart:始指针 preEnd:尾指针
in:中序数组
inStart:始指针 inEnd:尾指针
post:后序数组
postStart:始指针 postEnd:尾指针
从前序与后序遍历序列构造二叉树:
根节点指针为:preStart
由于前序数组的特性(根 左 右)得知,根节点的左子节点为pre[preStart+1],而后序数组的特性(左 右 根),根节点的左子节点在左子树的最后,可得index。
左子树:
后序:[postStart,index]-----(index-postStart) 左子树的数量
前序:[preStart+1,preStart+1+(index-postStart)]
右子树:
后序:[index+1,postEnd-1]-----(postEnd-1-(index+1))右子树的数量
前序:[preEnd-(postEnd-1-(index+1)),preEnd]
代码:
/**
* 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* constructFromPrePost(vector<int>& pre, vector<int>& post) {
return helper(pre,post,0,pre.size()-1,0,post.size()-1);
}
TreeNode* helper(vector<int>& pre,vector<int>& post,int preStart,int preEnd,int postStart,int postEnd)
{
if(postStart>postEnd || preStart>preEnd) return nullptr;
TreeNode* root = new TreeNode(pre[preStart]);
if(preStart == preEnd) return root;
int index = postStart;
while(pre[preStart+1] != post[index])
{
index++;
}
root->left = helper(pre,post,preStart+1,preStart+1+(index-postStart),postStart,index);
root->right = helper(pre,post,preEnd-(postEnd-1-(index+1)),preEnd,index+1,postEnd-1);
return root;
}
};
从前序与中序遍历序列构造二叉树:
根节点指针为:preStart
通过根节点指针得知根节点的值,在中序数组中分开左右子树。
左子树:
中序:[inoStart,index-1]
前序:[preStart+1,preStart+1+index-1-inoStart]
右子树:
中序:[index+1,inoEnd]
前序:[preEnd-(inoEnd-(index+1)),preEnd]
代码:
/**
* 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>& pre, vector<int>& ino) {
return helper(pre,ino,0,pre.size()-1,0,ino.size()-1);
}
TreeNode* helper(vector<int>& pre,vector<int>& ino,int preStart,int preEnd,int inoStart,int inoEnd)
{
if(preStart>preEnd || inoStart>inoEnd) return nullptr;
TreeNode* root = new TreeNode(pre[preStart]);
if(pre[preStart] == pre[preEnd]) return root;
int index = inoStart;
while(pre[preStart] != ino[index])
{
index++;
}
root->left = helper(pre,ino,preStart+1,preStart+1+index-1-inoStart,inoStart,index-1);
root->right = helper(pre,ino,preEnd-(inoEnd-(index+1)),preEnd,index+1,inoEnd);
return root;
}
};
从中序与后序遍历序列构造二叉树:
根节点的值为:postEnd
通过根节点指针得知根节点的值,在中序数组中分开左右子树。
左子树:
中序:[inoStart,index-1]
后序:[postStart,postStart+(index-1-inoStart)]
右子树:
中序:[index+1,inoEnd]
后序:[postEnd-1-(inoEnd-(index+1)),postEnd-1]
代码:
/**
* 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>& ino, vector<int>& post) {
return helper(ino,post,0,ino.size()-1,0,post.size()-1);
}
TreeNode* helper(vector<int>& ino,vector<int>& post,int inoStart,int inoEnd,int postStart,int postEnd)
{
if(inoStart>inoEnd||postStart>postEnd) return nullptr;
TreeNode* root = new TreeNode(post[postEnd]);
if(postStart == postEnd) return root;
int index = inoStart;
while(post[postEnd] != ino[index])
{
index++;
}
root->left = helper(ino,post,inoStart,index-1,postStart,postStart+(index-1-inoStart));
root->right = helper(ino,post,index+1,inoEnd,postEnd-1-(inoEnd-(index+1)),postEnd-1);
return root;
}
};