根据层序遍历和中序遍历确定二叉树,输出先序遍历
更新
2022/3/14 发现acwing上有这道题目, 于是去提交测试,成功ac
题目传送门
思路
二叉树的键值一定要唯一,不然无法确定一颗二叉树。
给出层序遍历和中序遍历确定一颗二叉树,类似与给出先序遍历和中序遍历确定一颗二叉树的做法类似。
- 采用递归建树求解,我们先确定当前层序遍历区间的第一个结点,那么这个点就是当前区间中序遍历的根结点。
- 找到这个点在中序遍历区间的位置,那么左边就是左子树区间,右边就是右子树区间。
- 对于左子树区间,我们与当前层序遍历区间的值比较,提取出
l
e
f
t
left
left, 表示左子树的层序遍历结果,继续递归。右子树区间同理
例如下图的一颗二叉树,对于当前区间,根节点为 B B B,去中序遍历结果里面划分左右区间
[ A ] , [ E , D , F ] [A],[E,D,F] [A],[E,D,F]。
再去层序遍历里面确定左右区间的层序遍历结果:
l e f t = [ A ] , r i g h t = [ D E F ] left = [A ], right=[D E F] left=[A],right=[DEF], 接下来
- 存下根节点
- 递归左子树,传入左子树区间,和左子树层序遍历结果
- 递归右子树,传入右子树区间和右子树层序遍历结果。
参考代码
#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x; i<=y; ++i)
#define pushk push_back
using namespace std;
vector<char> level,mid,pre;
int n;
void dfs(int l,int r,vector<char> &level){
if(l>r) return ;
vector<char> left,right;
left.pushk('x'),right.pushk('y');
//确定根结点
char root = level[1];
//去中序遍历里面去找到左右子区间
int pos=-1;
rep(i,l,r){
if(root==mid[i]) {
pos = i;
break;
}
}
//确定left
rep(i,1,(int)level.size()-1){
rep(j,l,pos-1){
if(level[i]==mid[j]){
left.pushk(level[i]);
break;
}
}
}
//确定right
rep(i,1,(int)level.size()-1){
rep(j,pos+1,r){
if(level[i]==mid[j]){
right.pushk(level[i]);
break;
}
}
}
//根
pre.pushk(root);
//左
dfs(l,pos-1,left);
//右
dfs(pos+1,r,right);
return ;
}
int main() {
string A,B;
cin>>A>>B;
int n = A.size();
level.resize(n+2),mid.resize(n+2);
level.pushk('x'),mid.pushk('y');
rep(i,1,n) level[i]=B[i-1];
rep(i,1,n) mid[i]=A[i-1];
dfs(1,n,level);
rep(i,0,(int)pre.size()-1) printf("%c",pre[i]);
return 0;
}
废话
同学问俺的一道面试题,俺就试着写了写。由于无测试的OJ,本人只手动测试了几个数据都正确,若有错误,请各位指出!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话