【C++】二叉树进阶OJ题

news2024/11/29 22:52:33

​🌠 作者:@阿亮joy.
🎆专栏:《吃透西嘎嘎》
🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根
在这里插入图片描述

目录

    • 👉根据二叉树创建字符串👈
    • 👉二叉树的层序遍历 I 和 II👈
    • 👉二叉树的最近公共祖先👈
    • 👉二叉搜索树与双向链表👈
    • 👉从前序与中序遍历序列构造二叉树👈
    • 👉从后序与中序遍历序列构造二叉树👈
    • 👉总结👈

👉根据二叉树创建字符串👈

给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。

空节点使用一对空括号对 “()” 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

在这里插入图片描述

思路:本道题就是前序遍历创建字符串,创建字符串时需要用括号将左右子树括起来。当左右子树都为空时,可以省略掉左右子树的括号。当左子树不为空,右子树为空时,可以省略掉右子树的括号。当左子树为空,右子树不为空时,左子树的括号不能省略掉。

class Solution 
{
public:
    string tree2str(TreeNode* root) 
    {
        if(root == nullptr)
            return string();
        
        string str;
        str += to_string(root->val);
        // 左边不为空或者左边为空右边不为空,需要加括号
        if(root->left || root->right)
        {
            str += '(';
            str += tree2str(root->left);
            str += ')';
        }
		// 右边不为空,需要加括号
        if(root->right)
        {
            str += '(';
            str += tree2str(root->right);
            str += ')';
        }

        return str;
    }
};

在这里插入图片描述

以上的解法还可以优化一下,因为返回值是string,会存在比较多的拷贝构造,我们可以通过引用和调用子函数的方式来优化。

class Solution 
{
private:
    void _tree2str(TreeNode* root, string& str)
    {
        if(root == nullptr)
            return;

        str += to_string(root->val);
        if(root->left || root->right)
        {
            str += '(';
            str += tree2str(root->left);
            str += ')';
        }

        if(root->right)
        {
            str += '(';
            str += tree2str(root->right);
            str += ')';
        }
    }
public:
    string tree2str(TreeNode* root) 
    {
        string str;
        _tree2str(root, str);
        return str;
    }
};

在这里插入图片描述


👉二叉树的层序遍历 I 和 II👈

二叉树的层序遍历 I

给你二叉树的根节点 root ,返回其节点值的层序遍历。 (即逐层地,从左到右访问所有节点)。

在这里插入图片描述

思路一:

  • 首先定义一个队列q和当前层的节点个数levelSize = 0
  • 当根节点root不为空时,根节点如队列q,且将levelSize设置为 1
  • 当队列不为空时,while循环进行。while循环内部用for循环来控制出一层的节点,出的同时需要将所出节点的左右孩子也让入队列中(如果有的话)。
  • for结束后,队列的size就是下一层的节点个数了。
  • while循环结合后,就能够得到二维数组了。

在这里插入图片描述

class Solution 
{
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        queue<TreeNode*> q;
        size_t levelSize = 0;
        if(root)
        {
            q.push(root);
            levelSize = 1;
        }

        vector<vector<int>> vv;
        while(!q.empty())
        {
            vector<int> v;
            // 控制一层一层出
            for(int i = 0; i < levelSize; ++i)
            {
                TreeNode* top = q.front();
                v.push_back(top->val);
                q.pop();

                if(top->left)
                    q.push(top->left);
                if(top->right)
                    q.push(top->right);
            }

            vv.push_back(v);
            // 当前层出完了,下一层的节点都进队列了,队列的size就是下一层的节点个数
            levelSize = q.size();
        }

        return vv;
    }
};

在这里插入图片描述


思路二:

  • 先申请一个队列q,如果根节点root不为空,根节点入队列
  • 然后定义两个TreeNode*变量curend = rootnextend = nullptrcurend为当前层的最后一个节点,next是下一层的最后一个节点。
  • 当队列不为空,while循环继续。队头所出的节点记为front,将front->val尾插到一位数组v中。然后front的左右孩子入队列(如果有的话),入的同时将nextend更新为最后入队列的节点。
  • 当所出节点front等于当前层最后的节点curend时,说明当前层所有节点的值已经收集完毕,即可将一维数组v尾插到二维数组vv中。然后还需要做以下操作:清空一维数组v;准备收集下一层节点的值,更新当前层的最后一个节点curend = nextendnext置为空(可以不做,最好做)
  • while循环结束,二维数组vv存储的就是层序遍历的结果。
class Solution 
{
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        queue<TreeNode*> q;
        if(root)
        {
            q.push(root);
        }

        vector<vector<int>> vv;
        TreeNode* curend = root;    // 当前层最后一个节点
        TreeNode* nextend = nullptr;    // 下一层最后一个节点
        vector<int> v;
        while(!q.empty())
        {
            TreeNode* front = q.front();
            v.push_back(front->val);
            q.pop();

            if(front->left)
            {
                q.push(front->left);
                nextend = front->left;
            }
            if(front->right)
            {
                q.push(front->right);
                nextend = front->right;
            }
            // 当front等于curend时,说明当前层所有节点的值已收集完毕
            // 可以准备收集下一层节点的值
            if(front == curend)
            {
                vv.push_back(v);    
                v.clear();  // 清空一维数组
                curend = nextend;   // 更新curend
            }
        }

        return vv;
    }
};
class Solution 
{
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        queue<TreeNode*> q;
        if(root)
        {
            q.push(root);
        }

        vector<vector<int>> vv;
        TreeNode* curend = root;    // 当前层最后一个节点
        TreeNode* nextend = nullptr;    // 下一层最后一个节点
        vector<int> v;
        while(!q.empty())
        {
            TreeNode* front = q.front();
            v.push_back(front->val);
            q.pop();

            // 只要是下一层节点入了队列,就需要更新nextend为入队列的节点
            if(front->left)
            {
                q.push(front->left);
                nextend = front->left;
            }
            if(front->right)
            {
                q.push(front->right);
                nextend = front->right;
            }
            // 当front等于curend时,说明当前层所有节点的值已收集完毕
            // 可以准备收集下一层节点的值
            if(front == curend)
            {
                vv.push_back(v);    
                v.clear();  // 清空一维数组
                curend = nextend;   // 更新curend
            }
        }

        return vv;
    }
};

在这里插入图片描述
注:以上两种方法还有用来求二叉树的最大宽度。

其实还有一种思路:双队列也可以解决这道题。一个队列存储节点,另一个队列存节点的所在层数,大家可以尝试一下。

在这里插入图片描述


二叉树的层序遍历 II

给你二叉树的根节点 root ,返回其节点值自底向上的层序遍历。(即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

在这里插入图片描述

我们只需要将二叉树的层序遍历 I 中得到的二维数组vv反转一下就能够解决这道题了。

class Solution 
{
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) 
    {
        queue<TreeNode*> q;
        size_t levelSize = 0;
        if(root)
        {
            q.push(root);
            levelSize = 1;
        }

        vector<vector<int>> vv;
        while(!q.empty())
        {
            vector<int> v;
            // 控制一层一层出
            for(int i = 0; i < levelSize; ++i)
            {
                TreeNode* top = q.front();
                v.push_back(top->val);
                q.pop();

                if(top->left)
                    q.push(top->left);
                if(top->right)
                    q.push(top->right);
            }

            vv.push_back(v);
            // 当前层出完了,下一层的节点都入队列了,队列的size就是下一层节点的个数
            levelSize = q.size();
        }

        reverse(vv.begin(), vv.end());
        return vv;
    }
};

在这里插入图片描述

👉二叉树的最近公共祖先👈

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

在这里插入图片描述
在这里插入图片描述

思路一:

在这里插入图片描述

class Solution 
{
private:
    // 查找节点x是否在以sub为根节点的树中
    bool Find(TreeNode* sub, TreeNode* x)
    {
        if(sub == nullptr)
            return false;
        
        return sub == x
            || Find(sub->left, x)
            || Find(sub->right, x);
    }
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        if(root == nullptr)
            return nullptr;
        
        // 其中一个节点为根节点,则最近公共祖先为根节点
        if(root == p || root == q)
            return root;

        // p、q在根节点的左右子树中
        bool pInLeft, pInRight, qInLeft, qInRight;
        pInLeft = Find(root->left, p);
        pInRight = !pInLeft;
        qInLeft = Find(root->left, q);
        qInRight = !qInLeft;

        if(pInLeft && qInLeft)  // p、q都在根节点的左子树中,转化成子问题
            return lowestCommonAncestor(root->left, p, q);
        else if(pInRight && qInRight)   // p、q都在根节点的右子树中,转化成子问题
            return lowestCommonAncestor(root->right, p, q);
        else    // p、q一个在左,另一个在右,最近公共祖先为根节点
            return root;
    }
};

在这里插入图片描述

注:因为 p 和 q 一定在树中,所以 p 在左子树,那么它一定不会在右子树中,q 同理。这种解法的时间复杂度为O(h*N)h为树的高度,N为节点的个数。

思路二:
这种思路是求出从根节点rootpq的路径,路径用栈来存储。因为路径长短不一样,所以先让长的弹出长度差个节点,然后两个栈一起弹出节点直至栈顶节点相同,那么栈顶节点就是pq的最近公共祖先。这种解法的思路类似于链表相交的思路,时间复杂度为O(N)

在这里插入图片描述

class Solution 
{
private:
    bool FindPath(TreeNode* root, TreeNode* x, stack<TreeNode*>& path)
    {
        if(root == nullptr)
            return false;

        path.push(root);
        if(root == x)   // 根节点就是p、q
            return true;
        if(FindPath(root->left, x, path))   // p、q在root的左子树中
            return true;
        if(FindPath(root->right, x, path))  // p、q在root的右子树中
            return true;
        
        path.pop();     // 经过root无法到达p、q,所以要将root弹出
        return false;
    }
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        stack<TreeNode*> pPath, qPath;
        FindPath(root, p, pPath);   // pPath中储存的是root到p的路径
        FindPath(root, q, qPath);   // qPath中储存的是root到q的路径

        // 路径长的弹出长度差个节点
        while(pPath.size() != qPath.size())
        {
            if(pPath.size() > qPath.size())
                pPath.pop();
            else
                qPath.pop();
        }
        
        // 栈顶节点相等时,栈顶节点就是最近公共祖先
        while(pPath.top() != qPath.top())
        {
            pPath.pop();
            qPath.pop();
        }

        return pPath.top();
    }
};

在这里插入图片描述

思路三:

思路三是思路一的精简版本,时间复杂度为O(N)

在这里插入图片描述

class Solution 
{
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        // root为空或者是p、q中的一样都要返回自己
        if(root == nullptr || root == p || root == q)
            return root;
        
        TreeNode* InLeft = lowestCommonAncestor(root->left, p, q);
        TreeNode* InRight = lowestCommonAncestor(root->right, p, q);

        // InLeft和InRight都不为空,则根节点为最近公共祖先
        if(InLeft && InRight)
            return root;
        
        // InLeft和InRight谁不为空,谁就是最近公共祖先
        return InLeft ? InLeft : InRight;
    }
};

在这里插入图片描述


👉二叉搜索树与双向链表👈

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。

在这里插入图片描述
在这里插入图片描述

思路:本道题要求左指针 left 指向中序的前一个节点,右指针 right 指向中序的后一个节点。我们可以采用prev来记录当前节点cur的前一个节点,那么prev->right = cur, cur->left = prev,这样就可以将二叉搜索树转化成双向链表了。注意:prevNode*的引用,这样才能链接起来。

class Solution 
{
private:
    void InordertreeToDoublyList(Node* cur, Node*& prev)
    {
        if(cur == nullptr)
            return;
        
        InordertreeToDoublyList(cur->left, prev);
        cur->left = prev;
        if(prev != nullptr)
            prev->right = cur;
        prev = cur;
        InordertreeToDoublyList(cur->right, prev);
    }
public:
    Node* treeToDoublyList(Node* root) 
    {
    	// 根节点为空,直接返回nullptr即可
        if(root == nullptr)
            return nullptr;
        
        Node* prev = nullptr;
        InordertreeToDoublyList(root, prev);
        // 找到中序第一个节点
        Node* first = root;
        while(first->left)
        {
            first = first->left;
        }
        // 找到中序最后一个节点
        Node* last = root;
        while(last->right)
        {
            last = last->right;
        }
        // 第一个节点与最后一个节点链接起来形成双向循环链表
        first->left = last;
        last->right = first;

        return first;
    }
};

在这里插入图片描述

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

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

在这里插入图片描述
在这里插入图片描述

思路:前序结果创建树,中序分割左右子树。子树区间确认是否继续递归创建子树,区间不存在则是空树。

class Solution 
{
private:
    TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int& preI, int inBegin, int inEnd)
    {
        if(inBegin > inEnd)
            return nullptr;
        
        // 构建根
        TreeNode* root = new TreeNode(preorder[preI]);
        // 用中序结果来分割左右子树
        int inI = inBegin;
        while(inI <= inEnd)
        {
            if(inorder[inI] == root->val)
                break;
            else
                ++inI;
        }

        // [inBegin, inI - 1] inI [inI + 1, inEnd]
        // 先构建左子树再构建右子树
        ++preI;    // 找出左右子树的根
        root->left = _buildTree(preorder, inorder, preI, inBegin, inI - 1);
        root->right = _buildTree(preorder, inorder, preI, inI + 1, inEnd);
        
        return root;
    }
public:


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

在这里插入图片描述
注:因为preI是遍历前序数组preinorde的下标,整个递归遍历中都要使用,所以需要传引用。如果不是传引用而是传值的话,左子树构建好返回。因为preI不是引用,只是形参,无法将上一次递归的结果保留下来,那么这样就无法找到右子树的根了,也就无构建右子树了。

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

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

在这里插入图片描述
在这里插入图片描述

思路:后序结果创建树,中序分割左右子树。子树区间确认是否继续递归创建子树,区间不存在则是空树。因为后序遍历序列是左子树、右子树、根,所以后序遍历序列的最后一个元素是根节点,位于它前面的是右子树的根节点。所以先要构建右子树,再来构建左子树。最后把根和左右子树链接在一起,二叉树就构建完成了。

class Solution 
{
private:
    TreeNode* _buildTree(vector<int>& inorder, vector<int>& postorder, int& posI, int inBegin, int inEnd)
    {
        if(inBegin > inEnd)
            return nullptr;
        
        TreeNode* root = new TreeNode(postorder[posI]);
        // 中序分割左右子树
        int inI = inBegin;
        while(inI <= inEnd)
        {
            if(inorder[inI] == root->val)
                break;
            else
                ++inI;
        }

        // 先构建右子树再构建左子树
        // [inBegin, inI - 1] inI [inI + 1, inEnd]
        --posI;
        root->right = _buildTree(inorder, postorder, posI, inI + 1, inEnd);;
        root->left = _buildTree(inorder, postorder, posI, inBegin, inI - 1);

        return root;
    }
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) 
    {
        int i = postorder.size() - 1;
        return _buildTree(inorder, postorder, i, 0, inorder.size() - 1);
    }
};

在这里插入图片描述
注:中序与后序遍历序列是无法确定唯一的一块树的,使用两个遍历结果确定树的结构, 其中有一个遍历结果必须要是中序遍历结果。

👉总结👈

本篇博客主要讲解了二叉树进阶的 OJ 题,每道题都是非常经典的面试题。那么以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家!💖💝❣️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166025.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端开发:Webpack的使用总结

前言 在前端开发过程中&#xff0c;尤其是现在前端框架的频繁使用的当下&#xff0c;作为前端开发者想必对于Webpack并不陌生&#xff0c;尤其是在使用Vue框架做前端开发的时候&#xff0c;打包时候必用Webpack。还有就是在前端求职面试的时候&#xff0c;Webpack相关的知识点…

mysql新建分区设置阈值(less than)引发的问题

mysql新建分表后&#xff0c;入库之前分表区间的数据&#xff0c;但是再分表中查询不到对应数据。 文章目录问题背景问题解析新建分区sql查看分区查询数据查询数据所在分区修改方案总结LESS THAN相关sql查询分区删除分区先建分区问题背景 初始化表的时候&#xff0c;先建的日期…

(二)Jenkins全局工具配置

目录 1、插件管理 2、Gitee安装 2.1、插件安装 2.2、查看Gitee状态 2.3、配置Gitee 2.4、获取私人令牌 2.5、测试连接 3、全局配置jdk、ant、maven 3.1、jdk配置 3.2、ant配置 3.3、maven配置 4、插件镜像下载地址配置 (一)Jenkins部署、基础配置介绍在windows下安…

事务(transaction)

事务&#xff08;重点 五颗星 ***** 必须理解 必须掌握&#xff09; 1、什么是事务&#xff1a; 一个事务其实就是一个完整的业务逻辑。 假设转账&#xff0c;从A账户向B账户转账10000.将A账户的钱减去10000&#xff08;update语句&#xff09;&#xff0c;将B账 户的钱增加100…

【手写 Vue2.x 源码】第二十六篇 - 数组依赖收集的实现

一&#xff0c;前言 上篇&#xff0c;主要介绍了数组依赖收集的原理 本篇&#xff0c;数组依赖收集的实现 二&#xff0c;对象依赖收集的总结 {}.dep > watcher 目前&#xff0c;“对象本身”和“对象中的每一个属性”都拥有一个 dep 属性&#xff0c;用于做依赖收集 此…

Leetcode:669. 修剪二叉搜索树(C++)

目录 问题描述&#xff1a; 实现代码与解析&#xff1a; 递归&#xff1a; 原理思路&#xff1a; 后序递归&#xff1a; 原理思路&#xff1a; 迭代&#xff1a; 原理思路&#xff1a; 问题描述&#xff1a; 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界…

#9文献学习--基于元强化学习的边缘计算快速自适应任务卸载

文献&#xff1a;Fast Adaptive Task Offloading in Edge Computing based on Meta Reinforcement Learning 基于深度强化学习DRL的方法&#xff0c;样本效率很低&#xff0c;需要充分的再培训来学习新环境的更新策略&#xff0c;对新环境的适应性很弱。 基于元强化学习的任务…

【数据结构与算法】第十八篇:递归,尾递归,尾调用

知识概览一、递归的引入&#xff08;递归现象&#xff09;二、递归的调用过程与实例分析三、递归的基本思想小tip:链表递归的具体实例四、递归的一般使用条件五、实例分析&#xff1a;斐波那契数列1.原理剖析2.fib优化1 – 记忆化3.fib优化24.fib优化3六、实例分析&#xff1a;…

mac下ssh连接docker使用centos

配置ssh连接docker本机信息 Apple M2/ macOS Ventura 13.1完整实现如下&#xff1a;使用docker下载centos镜像docker pull centos:centos7 # centos7 指定安装版本查看本地镜像# 使用以下命令查看是否已安装了centos7➜ ~ docker images REPOSITORY TAG IMAGE ID …

c++通讯录管理系统

结构体1&#xff0c;知识点&#xff08;结构体&#xff09;&#xff0c;存放人员详情&#xff0c;名字&#xff0c;性别&#xff0c;年龄等 struct person { string m_name; int m_sex; int m_age; string m_phone; string m_addr; };结构体2&#xff0c;知识点 &#xff08;结…

狗厂的N+1+2毕业,我觉得还是挺良心的

最近又跟朋友打听到了新鲜事&#xff0c;年底的新鲜事&#xff0c;什么209万&#xff0c;就是听个乐子&#xff0c;离我太远&#xff0c;什么HR和技术人员产生矛盾&#xff0c;一巴掌眼镜都打飞了&#xff0c;好乱套&#xff0c;今天我跟朋友打听了一些不太乱套的 一、鹅肠 1.…

Quartz认知篇 - 初识分布式任务调度Quartz

定时任务的使用场景 在遇到如下几种场景可以考虑使用定时任务来解决&#xff1a; 某个时刻或者时间间隔执行任务 批量数据进行处理 对两个动作进行解耦 Quartz 介绍 Quartz 是一个特性丰富的、开源的任务调度库&#xff0c;几乎可以嵌入所有的 Java 程序&#xff0c;包括很…

基于二叉树的改进SPIHT算法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

电脑怎么设置动态壁纸?关于Windows和Mac壁纸的设置方法

为了让电脑桌面更加美观舒适&#xff0c;很多人都会给电脑的桌面设置自己喜欢的壁纸。图片壁纸很多人都会设置&#xff0c;但是电脑怎么设置动态壁纸&#xff1f;这是很多人的困扰。其实方法同样很简单&#xff0c;下面有关于Windows和Mac动态壁纸的设置方法&#xff0c;一起来…

【阶段四】Python深度学习03篇:深度学习基础知识:神经网络可调超参数:激活函数、损失函数与评估指标

本篇的思维导图: 神经网络可调超参数:激活函数 神经网络中的激活函数(有时也叫激励函数)。 在逻辑回归中,输入的特征通过加权、求和后,还将通过一个Sigmoid逻辑函数将线性回归值压缩至[0,1]区间,以体现分类概率值。这个逻辑函数在神经网络中被称为…

PyCharm调用远程Python解释器

PyCharm调用远程Python解释器 PyCharm中直接调用远程服务器中Python解释器&#xff1a; 本地不用搭建Python环境。既避免了本地使用Window而服务器使用Linux系统不统一情况&#xff0c;又不用担心本地调试没问题而放到服务器上就出现问题。 PyCharm中打开项目并设置Python解释…

封装chrome镜像

chrome镜像 selenium提供了一个镜像&#xff0c;但这个镜像里面包含了比较多的东西&#xff1a; 镜像地址-github supervisord java chrome webDriver 实际的使用中遇到了一些问题 chrome遇到一些比较耗费内存和cup的操作的时候&#xff0c;有的时候会kill掉java进程&a…

干货 | 大数据交易所数据安全流通体系标准化尝试

以下内容整理自清华大学《数智安全与标准化》课程大作业期末报告同学的汇报内容。第一部分&#xff1a;国内大数据交易所发展现状第二部分&#xff1a;国外大数据交易模式及法律法规欧盟的数据交易模式是基于2022年5月16日所提出的《数据治理法案》&#xff0c;其中提出了数据中…

【C++11】—— 包装器

目录 一、function包装器 1. function包装器基本介绍 2. function包装器统一类型 3. function包装器的使用场景 二、bind包装器 一、function包装器 1. function包装器基本介绍 function包装器 也叫作适配器。C中的function本质是一个类模板&#xff0c;也是一个包装器…

第四章 基本数据

在第2章中&#xff0c;我们讨论了多种导入数据到R中的方法。遗憾的是&#xff0c;将你的数据表示为矩阵或数据框这样的矩形形式仅仅是数据准备的第一步。这里可以演绎Kirk船长在《星际迷航》“末日决战的滋味”一集中的台词&#xff08;这完全验明了我的极客基因&#xff09;&a…