根据前序遍历和中序遍历恢复原二叉树
前序遍历的第一个元素是根,设其为r,则可以在中序遍历中找到r,并分别确定左右子树的前序遍历和中序遍历。这样递归求解即可。
注意,在中序遍历中查找r时,可以不用遍历,而是预处理出每个r在中序遍历I中的位置invI,这样就可以在O(1)的时间查找到。
是否可以生成一棵二叉树的条件为,每一次递归,判断r在中序遍历中的位置,是否在当前中序遍历数组的范围内即可。
例题:
F - Pre-order and In-order
https://atcoder.jp/contests/abc255/tasks/abc255_f
参考代码
官方:返回值为当前范围的序列是否可以生成二叉树,在序列中直接获取左右子树

#include <iostream> using namespace std; int n; int P[200005], I[200005], Iinv[200005]; int L[200005], R[200005]; bool solve(int s, int t, int S, int T) { int r = P[s], p = Iinv[r]; if(p < S || T < p) return false; if(p-S > 0){ L[r] = P[s+1]; if(!solve(s+1, s+p-S, S, p-1)) return false; } if(T-p > 0){ R[r] = P[s+p-S+1]; if(!solve(s+p-S+1, t, p+1, T)) return false; } return true; } int main(void) { cin >> n; for(int i = 1; i <= n; i++) cin >> P[i]; for(int i = 1; i <= n; i++) cin >> I[i]; for(int i = 1; i <= n; i++) Iinv[I[i]] = i; if(P[1] != 1 || !solve(1, n, 1, n)){ cout << -1 << endl; return 0; } for(int i = 1; i <= n; i++) cout << L[i] << " " << R[i] << endl; return 0; }
自写:返回值为根节点标号,递归用返回值获取左右子树,用全局flag记录是否可以生成二叉树

#include<bits/stdc++.h> using namespace std; typedef long long LL; int l[200010]; int r[200010]; int pre[200010]; int in[200010]; int val_to_index[200010]; int n; bool flag = true; int dfs(int l1, int r1, int l2, int r2) { if (!flag) return -1; if (r1 < l1) return 0; if (r1 == l1) { l[pre[l1]] = 0; r[pre[l1]] = 0; return pre[l1]; } int root = pre[l1]; int index = val_to_index[root]; if (index<l2||index>r2) { flag = false; return -1; } l[root] = dfs(l1 + 1, l1 + index - l2, l2, index - 1); if (!flag) return -1; r[root] = dfs(l1 + index - l2 + 1, r1, index + 1, r2); if (!flag) return -1; return root; } void YD() { cin >> n; for (int i = 1; i <= n; i++) cin >> pre[i]; for (int i = 1; i <= n; i++) { cin >> in[i]; val_to_index[in[i]] = i; } dfs(1, n, 1, n); if (!flag||pre[1]!=1) { cout << -1 << endl; return; } for (int i = 1; i <= n; i++) { cout << l[i] << ' ' << r[i] << endl; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int T = 1; //cin >> T; while (T--) { YD(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人