当前位置:首页 > 牛客 > 牛客25665题详解:二叉树重建与三种遍历实现

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

6小时前

牛客25665题详解:二叉树重建与三种遍历实现 二叉树重建 层序遍历 中序遍历 前序遍历 后序遍历 第1张

一、题目解读

牛客25665题要求根据给定的层序遍历中序遍历序列重建二叉树,并输出:

    1.所有叶子节点(从左到右)

    2.前序遍历序列

    3.后序遍历序列

二、解题思路

1.代码采用分治算法实现:

    使用哈希表记录中序遍历位置

2.递归构建二叉树:

    每次取层序首个元素作为根节点

    根据中序分割左右子树

    筛选层序中属于左/右子树的元素

3.三种遍历实现:

    前序:根→左→右

    后序:左→右→根

    叶子节点:左右子节点均为空

三、解题步骤

1.读取输入数据(层序+中序)

2.建立中序遍历位置索引

3.递归构建二叉树

4.获取叶子节点和前序/后序遍历结果

5.格式化输出结果

四、完整代码实现

#include <iostream>
#include <vector>
#include <unordered_map>
#include <queue>
using namespace std;

struct TreeNode {
    int val;
    TreeNode *left, *right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

TreeNode* build(vector<int>& level, vector<int>& in, 
               int inStart, int inEnd, unordered_map<int,int>& pos) {
    if (level.empty() || inStart > inEnd) return nullptr;
    
    TreeNode* root = new TreeNode(level[0]);
    int idx = pos[level[0]];
    
    vector<int> leftLevel, rightLevel;
    unordered_map<int,bool> inLeft;
    for (int i = inStart; i < idx; i++) 
        inLeft[in[i]] = true;
    
    for (int i = 1; i < level.size(); i++) {
        if (inLeft.count(level[i])) 
            leftLevel.push_back(level[i]);
        else 
            rightLevel.push_back(level[i]);
    }
    
    root->left = build(leftLevel, in, inStart, idx-1, pos);
    root->right = build(rightLevel, in, idx+1, inEnd, pos);
    return root;
}

void getLeaves(TreeNode* root, vector<int>& res) {
    if (!root) return;
    if (!root->left && !root->right) 
        res.push_back(root->val);
    getLeaves(root->left, res);
    getLeaves(root->right, res);
}

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

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    vector<int> level, in;
    string line;
    
    // 读取层序遍历
    getline(cin, line);
    size_t pos = 0;
    while ((pos = line.find(' ')) != string::npos) {
        level.push_back(stoi(line.substr(0, pos)));
        line.erase(0, pos + 1);
    }
    if (!line.empty()) level.push_back(stoi(line));
    
    // 读取中序遍历
    getline(cin, line);
    pos = 0;
    while ((pos = line.find(' ')) != string::npos) {
        in.push_back(stoi(line.substr(0, pos)));
        line.erase(0, pos + 1);
    }
    if (!line.empty()) in.push_back(stoi(line));
    
    // 建立中序位置索引
    unordered_map<int, int> inPos;
    for (int i = 0; i < in.size(); i++) 
        inPos[in[i]] = i;
    
    // 重建二叉树
    TreeNode* root = build(level, in, 0, in.size()-1, inPos);
    
    // 处理输出
    vector<int> leaves, pre, post;
    getLeaves(root, leaves);
    traversal(root, pre, 1);
    traversal(root, post, 2);
    
    // 输出结果
    for (int i = 0; i < leaves.size(); i++) 
        cout << (i ? " " : "") << leaves[i];
    cout << endl;
    
    for (int i = 0; i < pre.size(); i++) 
        cout << (i ? " " : "") << pre[i];
    cout << endl;
    
    for (int i = 0; i < post.size(); i++) 
        cout << (i ? " " : "") << post[i];
    cout << endl;
    
    return 0;
}

五、总结

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

原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。