【算法题】 面试级别的二叉树题目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;
    
    }
};

相关推荐
菜菜的顾清寒15 小时前
力扣100(38)堆-数组中的第K个最大元素
算法·leetcode·排序算法
全球通史15 小时前
Jetson Nano 双摄像头芯片检测视觉系统:小尺度难定位问题解决,从零开始实现教程说明
嵌入式硬件·算法·ubuntu·性能优化
千寻girling15 小时前
机器学习 | 监督学习算法(了解) | 尚硅谷学习
开发语言·人工智能·后端·python·学习·算法·机器学习
阿方.91815 小时前
C++ string 超全精讲 | 从零使用、底层原理、手搓简易string、高频考点、易错点、面试手撕
开发语言·c++·字符串·string·知识分享
强盛机器学习~15 小时前
2026年SCI一区新算法-灰叶猴优化算法(GLO)-公式原理详解与性能测评 Matlab代码免费获取
算法·matlab·进化计算·群体智能·智能优化算法·元启发式算法
fish_xk15 小时前
c++11(二)
java·前端·c++
c2385615 小时前
MyVector模拟实现
算法
张小姐的猫15 小时前
【Linux】多线程实战 —— 日志类 | 策略模式
linux·运维·服务器·c++·bash·策略模式
圣保罗的大教堂15 小时前
leetcode 1871. 跳跃游戏 VII 中等
leetcode