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


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

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

给定两个整数数组 preorderinorder ,其中 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/

给定两个整数数组 inorderpostorder ,其中 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;
    
    }
};

相关推荐
裕晟资质规划3 小时前
军工保密资质二级申报的四个可量化硬条件:条文位置、数值口径与西安配套企业实务要点
java·服务器·网络·数据库·算法
LuminousCPP3 小时前
数据结构-排序(一):基础排序算法横向对比|冒泡、插入、希尔、堆与双向选择,详解二分 / Knuth 增量
c语言·数据结构·笔记·算法·排序算法
初願致夕霞3 小时前
C/C++传统程序内存分布(代码实测)
java·c语言·c++
牛油果子哥q3 小时前
C++对接LLM完整工程:异步HTTP请求、JSON解析、超时容错、重连兜底
c++·http·json
Nil2084 小时前
leetcode 46全排列
算法·leetcode·职场和发展
小白羊丨4 小时前
问数 Agent 整体架构、意图识别、历史上下文与 NL2SQL
java·面试·架构
辰烨chenye4 小时前
LeetCode Hot 100 题解 · 动态规划篇
算法·leetcode·动态规划
会周易的程序员4 小时前
aiDgeController软PLC控制通讯协议文档
c++·物联网·网关·iot·ipc·进程间通讯
B站计算机毕业设计超人4 小时前
计算机毕业设计知识图谱(Neo4j)+大语言模型LLM+GraphRAG图检索增强技术的考研院校推荐、分数线预测与智能问答系统(源码+文档+PPT+讲解)
大数据·人工智能·语言模型·毕业设计·知识图谱·课程设计·推荐算法
青山木4 小时前
Hot 100 --- 买卖股票的最佳时机
java·数据结构·算法·leetcode·贪心算法