【算法题】 面试级别的二叉树题目OJ复习(下)


从前序与中序遍历序列构造二叉树

105. 从前序与中序遍历序列构造二叉树https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

写法一:递归

cpp 复制代码
class Solution {
public:
    TreeNode* build(vector<int>& preorder, vector<int>& inorder,int& prev,int inbegin,int inend)
    {
        if(inbegin>inend)
        return nullptr;
        //前序确定根
        TreeNode* root=new TreeNode(preorder[prev]);
        //中序分割
        int rooti=inbegin;
        while(preorder[prev]!=inorder[rooti])
        rooti++;

        prev++;
        root->left =build(preorder,inorder,prev,inbegin,rooti-1);
        root->right=build(preorder,inorder,prev,rooti+1,inend);
        return root;

    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int i=0;
        return build(preorder,inorder,i,0,inorder.size()-1);
    }
};

写法二:哈希表

cpp 复制代码
class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int n = preorder.size();
        unordered_map<int, int> index;
        for (int i = 0; i < n; i++) {
            index[inorder[i]] = i;
        }

        auto dfs = [&](this auto&& dfs, int pre_l, int pre_r, int in_l) -> TreeNode* {
            if (pre_l == pre_r) { // 空节点
                return nullptr;
            }
            int left_size = index[preorder[pre_l]] - in_l; // 左子树的大小
            TreeNode* left = dfs(pre_l + 1, pre_l + 1 + left_size, in_l);
            TreeNode* right = dfs(pre_l + 1 + left_size, pre_r, in_l + 1 + left_size);
            return new TreeNode(preorder[pre_l], left, right);
        };
        return dfs(0, n, 0); // 左闭右开区间
    }
};

从中序与后序遍历序列构造二叉树

106. 从中序与后序遍历序列构造二叉树https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

cpp 复制代码
class Solution {
public:
    TreeNode* build(vector<int>& inorder, vector<int>& postorder,int& prev,int inbegin,int inend)
    {
    
        if(inbegin>inend)
        return nullptr;
        //后序确定根
        TreeNode* root=new TreeNode(postorder[prev]);
        //中序分割
        int rooti=inbegin;
        while(inorder[rooti]!=postorder[prev])
        {
            rooti++;
            if(rooti==inorder.size())
            break;
        }
        
        if(prev==0)
        return root;
        prev--;
        
        root->right=build(inorder,postorder,prev,rooti+1,inend);
        root->left=build(inorder,postorder,prev,inbegin,rooti-1);
        
        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
     {
        int i=postorder.size()-1;
        return build(inorder,postorder,i,0,inorder.size()-1);
    }
};

二叉树的前序遍历

144. 二叉树的前序遍历https://leetcode.cn/problems/binary-tree-preorder-traversal/

给你二叉树的根节点 root ,返回它节点值的 前序遍历。

方法一:迭代

cpp 复制代码
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        TreeNode* rooti=root;
        vector<int> vv;
        
        while(rooti||!st.empty())
        {
            while(rooti)
            {
                vv.push_back(rooti->val);
                st.push(rooti);
                rooti=rooti->left;
            }
            TreeNode* top=st.top();
            rooti=top->right;
            st.pop();
        }
        return vv;
    }
};

方法二:Morris 遍历

cpp 复制代码
class Solution {
public:
    vector<int> preorderTraversal(TreeNode *root) {
        vector<int> res;
        if (root == nullptr) {
            return res;
        }

        TreeNode *p1 = root, *p2 = nullptr;

        while (p1 != nullptr) {
            p2 = p1->left;
            if (p2 != nullptr) {
                while (p2->right != nullptr && p2->right != p1) {
                    p2 = p2->right;
                }
                if (p2->right == nullptr) {
                    res.emplace_back(p1->val);
                    p2->right = p1;
                    p1 = p1->left;
                    continue;
                } else {
                    p2->right = nullptr;
                }
            } else {
                res.emplace_back(p1->val);
            }
            p1 = p1->right;
        }
        return res;
    }
};

二叉树的中序遍历

94. 二叉树的中序遍历https://leetcode.cn/problems/binary-tree-inorder-traversal/

给定一个二叉树的根节点 root ,返回 它的 中序 遍历

cpp 复制代码
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        TreeNode* rooti=root;
        stack<TreeNode*> st;
        vector<int> vv;
        
        while(rooti||!st.empty())
        {
            while(rooti)
            {
                st.push(rooti);
                rooti=rooti->left;
            }
            TreeNode* top=st.top();
            vv.push_back(top->val);
            st.pop();
            rooti=top->right;
        }
        return vv;
    }
};

二叉树的后序遍历

145. 二叉树的后序遍历https://leetcode.cn/problems/binary-tree-postorder-traversal/

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。

cpp 复制代码
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
    
        TreeNode* rooti=root;
        TreeNode* prev=nullptr;
        stack<TreeNode*> st;
        vector<int> vv;
        
        while(rooti||!st.empty())
        {
            while(rooti)
            {
                st.push(rooti);
                rooti=rooti->left;
            }
            TreeNode* top=st.top();
            
            if(top->right&&prev!=top->right)
            {
                rooti=top->right;
            }
            else
            {
                vv.push_back(top->val);
                st.pop();
                prev=top;
            }
        }
        return vv;
    
    }
};

相关推荐
inrichtt4 小时前
第八课时:SPI总线揭秘:四线全双工通信的奥
c语言·数据结构·stm32·单片机·嵌入式硬件
救救孩子把5 小时前
AI面试八股文-21_21-多模态Agent面试题-Vision-Language-Agent
人工智能·面试·职场和发展·llava·多模态agent
HPtiger5 小时前
数据结构——选择排序
数据结构·算法·排序算法
康实训5 小时前
老年评估仿真实训平台架构设计与老年人能力评估实训室教学落地实践
大数据·人工智能·算法·实训室·实训室建设
DongQiShanRen5 小时前
六根硬件映射(四):归属澄清、两处不一致与卷十一总表
开发语言·人工智能·算法·rust·哈希算法·集成学习
CCblandy5 小时前
雪花 ID 四个边界实测:时钟回拨重号 500 个,前端 JSON.parse 直接丢精度
后端·python·算法·性能优化·架构
丑梨数据5 小时前
信创环境里跑文档工具:格式兼容与本地合规的几个坑
数据结构·人工智能·算法·决策树·排序算法
烂蜻蜓6 小时前
Pandas入门教程(四):Series数据结构——创建、索引与常用方法
数据结构·pandas
把我格子衫拿来6 小时前
VTK 9.5 与 Qt 6 联合开发:从嵌入三维窗口到可维护的桌面架构
c++·python·qt·vtk·三维可视化
无忧.芙桃6 小时前
C++语言原理与实践(十六):多态机制讲解
开发语言·c++·多态