找回密码
 立即注册
查看: 13|回复: 0

牛客25665题详解:二叉树重建与三种遍历实现

[复制链接]
  • 打卡等级:即来则安
  • 打卡总天数:16
  • 打卡月天数:7
  • 打卡总奖励:111
  • 最近打卡:2025-07-12 15:59:47

21

主题

1

回帖

2469

积分

VIP会员

积分
2469
发表于 2025-6-26 10:36:33 | 显示全部楼层 |阅读模式
一、题目解读
牛客25665题要求根据给定的层序遍历中序遍历序列重建二叉树,并输出:
    1.所有叶子节点(从左到右)
    2.前序遍历序列
    3.后序遍历序列
二、解题思路
1.代码采用分治算法实现:
    使用哈希表记录中序遍历位置
2.递归构建二叉树:
    每次取层序**元素作为根节点
    根据中序分割左右子树
    筛选层序中属于左/右子树的元素
3.三种遍历实现:
    前序:根→左→右
    后序:左→右→根
    叶子节点:左右子节点均为空
三、解题步骤
1.读取输入数据(层序+中序)
2.建立中序遍历位置索引
3.递归构建二叉树
4.获取叶子节点和前序/后序遍历结果
5.格式化输出结果
四、完整代码实现C++

  1. struct TreeNode {
  2.     int val;
  3.     TreeNode *left, *right;
  4.     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  5. };

  6. TreeNode* build(vector<int>& level, vector<int>& in,
  7.                int inStart, int inEnd, unordered_map<int,int>& pos) {
  8.     if (level.empty() || inStart > inEnd) return nullptr;
  9.    
  10.     TreeNode* root = new TreeNode(level[0]);
  11.     int idx = pos[level[0]];
  12.    
  13.     vector<int> leftLevel, rightLevel;
  14.     unordered_map<int,bool> inLeft;
  15.     for (int i = inStart; i < idx; i++)
  16.         inLeft[in[i]] = true;
  17.    
  18.     for (int i = 1; i < level.size(); i++) {
  19.         if (inLeft.count(level[i]))
  20.             leftLevel.push_back(level[i]);
  21.         else
  22.             rightLevel.push_back(level[i]);
  23.     }
  24.    
  25.     root->left = build(leftLevel, in, inStart, idx-1, pos);
  26.     root->right = build(rightLevel, in, idx+1, inEnd, pos);
  27.     return root;
  28. }

  29. void getLeaves(TreeNode* root, vector<int>& res) {
  30.     if (!root) return;
  31.     if (!root->left && !root->right)
  32.         res.push_back(root->val);
  33.     getLeaves(root->left, res);
  34.     getLeaves(root->right, res);
  35. }

  36. void traversal(TreeNode* root, vector<int>& res, int type) {
  37.     if (!root) return;
  38.     if (type == 1) res.push_back(root->val); // pre
  39.     traversal(root->left, res, type);
  40.     traversal(root->right, res, type);
  41.     if (type == 2) res.push_back(root->val); // post
  42. }

  43. int main() {
  44.     ios::sync_with_stdio(false);
  45.     cin.tie(0);
  46.    
  47.     vector<int> level, in;
  48.     string line;
  49.    
  50.     // 读取层序遍历
  51.     getline(cin, line);
  52.     size_t pos = 0;
  53.     while ((pos = line.find(' ')) != string::npos) {
  54.         level.push_back(stoi(line.substr(0, pos)));
  55.         line.erase(0, pos + 1);
  56.     }
  57.     if (!line.empty()) level.push_back(stoi(line));
  58.    
  59.     // 读取中序遍历
  60.     getline(cin, line);
  61.     pos = 0;
  62.     while ((pos = line.find(' ')) != string::npos) {
  63.         in.push_back(stoi(line.substr(0, pos)));
  64.         line.erase(0, pos + 1);
  65.     }
  66.     if (!line.empty()) in.push_back(stoi(line));
  67.    
  68.     // 建立中序位置索引
  69.     unordered_map<int, int> inPos;
  70.     for (int i = 0; i < in.size(); i++)
  71.         inPos[in[i]] = i;
  72.    
  73.     // 重建二叉树
  74.     TreeNode* root = build(level, in, 0, in.size()-1, inPos);
  75.    
  76.     // 处理输出
  77.     vector<int> leaves, pre, post;
  78.     getLeaves(root, leaves);
  79.     traversal(root, pre, 1);
  80.     traversal(root, post, 2);
  81.    
  82.     // 输出结果
  83.     for (int i = 0; i < leaves.size(); i++)
  84.         cout << (i ? " " : "") << leaves[i];
  85.     cout << endl;
  86.    
  87.     for (int i = 0; i < pre.size(); i++)
  88.         cout << (i ? " " : "") << pre[i];
  89.     cout << endl;
  90.    
  91.     for (int i = 0; i < post.size(); i++)
  92.         cout << (i ? " " : "") << post[i];
  93.     cout << endl;
  94.    
  95.     return 0;
  96. }
复制代码

五、总结
本文详解了通过层序+中序重建二叉树的算法,实现了三种遍历方式。该解法时间复杂度O(n²),空间复杂度O(n),适合笔试面试准备。关键点在于递归分割中序序列和筛选层序子序列。
参考:牛客题解

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表