在曾经的博客中,曾经记录过这样一题:
二叉树遍历_牛客题霸_牛客网 (nowcoder.com)
1. 中序+前序
操作方法:前序确定根,中序分割区间
总结:
用前序的根去分割中序对应的区间,只要中序被分割之后还有数据区间,就继续分割;如果中序被分割之后区间为空,则直接返回。
代码实现:
因为每次递归都要传入一个新的区间,所以不能在原函数上递归。
class Solution {
public:
TreeNode* build(vector<int>& preorder, vector<int>& inorder,int& prei,int inbegin,int inend){
if(inbegin>inend){
return nullptr;
}
//inbegin和inend就是此轮递归我们要构建的区间,现在我们到这个区间中寻找前序对应的根
int rooti = inbegin;
while(rooti<=inend){//一定能在这个区间中找到
if(inorder[rooti]==preorder[prei]){
prei++;//前序往前走,便于下一轮递归找root
break;
}else{
rooti++;
}
}
//rooti已经走到了根的位置,区间分为[inbegin,rooti-1] rooti [rooti+1,inend]
TreeNode* root = new TreeNode(inorder[rooti]);
root->left = build( preorder, inorder, prei,inbegin, rooti-1);
root->right = build( preorder,inorder,prei,rooti+1, inend);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int prei = 0;
return build(preorder, inorder,prei,0,inorder.size()-1);
}
};
2. 中序+后序
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
一样的逻辑:
class Solution {
public:
TreeNode* build(vector<int>& inorder, vector<int>& postorder, int& posti,int inbegin,int inend){
if(inbegin>inend){
return nullptr;
}
int rooti = inbegin;
while(rooti<=inend){
if(inorder[rooti]==postorder[posti]){
posti--;
break;
}else{
rooti++;
}
}
//找到了,分为三个区间 [inbegin,rooti-1] rooti [rooti+1,inend]
TreeNode* root = new TreeNode(inorder[rooti]);
root->right = build(inorder, postorder, posti,rooti+1,inend);
root->left = build(inorder, postorder, posti,inbegin,rooti-1);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
int posti = postorder.size()-1;
return build(inorder,postorder,posti,0,inorder.size()-1);
}
};
还有就是注意在递归部分是先构建右子树,再构建左子树。