词嵌入(Word Embedding)之Word2Vec、GloVe、FastText

简介:个人学习分享,如有错误,欢迎批评指正。

词嵌入(Word Embedding)是一种将词语映射到低维稠密向量空间的技术,能够捕捉词与词之间的语义关系。Word2Vec、GloVe、FastText 是常见的词嵌入方法,它们各自有不同的原理和特点。

一、Word2Vec

Word2Vec是Google在2013年提出的一种词嵌入(Word Embedding)模型,其核心思想是将词语映射到一个连续的低维向量空间,使得语义相似的词在向量空间中距离更近。通过这种方式,词语的语义关系可以用向量之间的数学运算(如余弦相似度)来度量。

1.基本原理

Word2Vec 的核心思想是基于 分布式假设,即"上下文相似的词语具有相似的语义"。通过大量语料库的训练,Word2Vec 学习到每个词语的向量表示,使得这些向量能够捕捉词语之间的语义关系。

Word2Vec 主要有两种模型架构

  1. Continuous Bag-of-Words (CBOW) 模型:
  • 目标: 根据上下文预测中心词。
  • 原理 : 将上下文词向量求和或平均,输入到神经网络,预测中心词的概率分布
  • 特点: 适合小型数据集,训练速度较快。
  1. Skip-Gram 模型:
  • 目标: 根据中心词预测上下文词。
  • 原理 : 输入中心词的向量,通过神经网络,预测其周围上下文词的概率分布
  • 特点: 在大型数据集上表现更好,能够捕捉更多的稀有词信息。

向量性质和语义关系

Word2Vec 生成的词向量具有以下特点:

  1. 相似性捕捉: 语义相似的词语,其向量在空间中距离较近。

  2. 线性关系: 词向量之间的差异可以反映某些语义关系。 例如:

王国 ⃗ − 男人 ⃗ + 女人 ⃗ ≈ 王后 ⃗ \vec{王国} - \vec{男人} + \vec{女人} \approx \vec{王后} 王国 −男人 +女人 ≈王后

  1. 聚类效果: 同一类别的词语在向量空间中往往形成聚类。

2.模型结构

  1. CBOW 模型结构
  • 输入层 : 上下文词的one-hot 向量表示。
  • 投影层 : 将one-hot 向量映射到低维嵌入空间,通常使用嵌入矩阵。
  • 隐藏层 : 将上下文词的嵌入向量进行平均求和
  • 输出层 : 通过 softmax 函数,输出中心词的概率分布

数学公式:

给定上下文词 w c o n t e x t w_{context} wcontext,目标是最大化中心词 w t a r g e t w_{target} wtarget的条件概率:

P ( w t a r g e t ∣ w c o n t e x t ) = s o f t m a x ( v w t a r g e t T h ) P(w_{target} \mid w_{context}) = softmax(v_{w_{target}}^T h) P(wtarget∣wcontext)=softmax(vwtargetTh)

其中, h h h 是上下文词向量的平均值, v w t a r g e t v_{w_{target}} vwtarget 是中心词的输出向量。

  1. Skip-Gram 模型结构
  • 输入层 : 中心词的 one-hot 向量表示。
  • 投影层 : 将中心词的 one-hot 向量映射到嵌入空间
  • 输出层 : 通过 softmax 函数,预测上下文词的概率分布

数学公式:

给定中心词 w t a r g e t w_{target} wtarget,目标是最大化其上下文词 w c o n t e x t w_{context} wcontext的条件概率:

P ( w c o n t e x t ∣ w t a r g e t ) = s o f t m a x ( v w c o n t e x t T h ) P(w_{context} \mid w_{target}) = softmax(v_{w_{context}}^T h) P(wcontext∣wtarget)=softmax(vwcontextTh)

其中, h h h 是中心词的嵌入向量, v w c o n t e x t v_{w_{context}} vwcontext 是上下文词的输出向量。

3.训练方法和实践步骤

3.1.训练方法

由于词汇表通常非常大,直接计算 softmax 的代价过高。为此,Word2Vec 引入了两种高效的近似训练方法:

a.负采样 (Negative Sampling)

  • 思想: 只更新一小部分负样本的参数,而非整个词汇表。
  • 方法: 对于每个正样本(真实的词对),随机采样 k 个负样本(无关的词对),使模型区分正负样本。

负采样的基本原理

负采样通过简化优化目标,减少计算量。它的核心思想是:与其每次计算所有类别的softmax分布,不如仅针对正样本和少量负样本进行计算。这些负样本通过随机采样获得,而正样本是实际存在于数据中的正确标签。

具体步骤如下:

  • 正样本(Positive Sample):对于每个输入词语,模型会选择其上下文中的正确词语作为正样本。
  • 负样本(Negative
    Samples):为了降低计算量,模型随机选择若干个错误的词语作为负样本。负样本来自词汇表中的其他词语,通常是无关词。
  • 优化目标:模型不再优化整个词汇表的softmax概率分布,而是仅仅优化正样本与若干负样本的相对概率。

负采样数学表述

在传统的 Skip-Gram 模型中,目标是最大化每对词之间的共现概率:

P ( Context Word ∣ Target Word ) = e v c ⋅ v w ∑ w ′ ∈ V e v c ⋅ v w ′ P(\text{Context Word}|\text{Target Word}) = \frac{e^{v_c \cdot v_w}}{\sum_{w' \in V} e^{v_c \cdot v_{w'}}} P(Context Word∣Target Word)=∑w′∈Vevc⋅vw′evc⋅vw

其中 v c v_c vc 和 v w v_w vw 分别表示上下文词和目标词的词向量, V V V 是词汇表。

负采样优化目标如下:

L = log ⁡ σ ( v c ⋅ v w ) + ∑ i = 1 k log ⁡ σ ( − v c ⋅ v n i ) L = \log \sigma(v_c \cdot v_w) + \sum_{i=1}^{k} \log \sigma(-v_c \cdot v_{n_i}) L=logσ(vc⋅vw)+i=1∑klogσ(−vc⋅vni)

其中:

  • σ ( x ) \sigma(x) σ(x) 是 sigmoid 函数,用于将输出限制在 (0,1) 之间。
  • v n i v_{n_i} vni 是随机采样得到的负样本词向量。
  • k k k 是负采样的样本数量,通常取 5 到 20 之间。

b.层次化 Softmax (Hierarchical Softmax)

  • 思想: 将 softmax 分解为二叉树的形式,降低计算复杂度。
  • 方法: 将词汇表组织成霍夫曼编码的二叉树,预测路径上的二元决策。

3.2.实践步骤

  1. 语料预处理
  • 分词: 将文本切分为单词序列。
  • 去除停用词: 可根据需求去除常见但信息量低的词语。
  • 建立词汇表: 统计词频,建立词语索引的映射关系。
  1. 模型训练
  • 选择模型架构: CBOW 或 Skip-Gram。
  • 设定超参数: 嵌入维度、窗口大小、负采样数量、学习率等。
  • 训练参数: 使用优化算法(如 SGD)更新参数。
  1. 模型评估
  • 相似度测试: 计算词向量之间的余弦相似度,验证相似词是否接近。
  • 下游任务验证: 将词向量应用于具体任务,评估性能提升。

4.python代码实现

python 复制代码
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence

# 1. 加载语料
# 假设语料文件为 'corpus.txt',每行一个经过分词的句子,词语用空格分隔
sentences = LineSentence('corpus.txt')

# 2. 训练Word2Vec模型
model = Word2Vec(
    sentences,
    vector_size=100,   # 词向量的维度
    window=5,          # 上下文窗口大小
    min_count=5,       # 词频低于min_count的词将被忽略
    workers=4,         # 使用4个线程进行训练
    sg=1,              # 使用Skip-Gram模型;若为0,则使用CBOW模型
    negative=5,        # 负采样个数
    sample=1e-3,       # 下采样率
    epochs=5           # 迭代次数
)

# 3. 保存模型
model.save('word2vec.model')

# 4. 加载模型
model = Word2Vec.load('word2vec.model')

# 5. 使用模型

# 获取词向量
vector = model.wv['苹果']
print('苹果的词向量:')
print(vector)

# 计算两个词的相似度
similarity = model.wv.similarity('苹果', '香蕉')
print(f'苹果和香蕉的相似度:{similarity}')

# 找出与某个词最相似的词
similar_words = model.wv.most_similar('苹果', topn=5)
print('与苹果最相似的词:')
for word, score in similar_words:
    print(f'{word}: {score}')

# 6. 词向量的简单运算
result = model.wv.most_similar(positive=['王后', '男人'], negative=['女人'], topn=1)
print('王后 + 男人 - 女人 = ')
print(result)

5.总结

优势和局限性

优势:

  • 高效性: 相比传统的共现矩阵和 SVD 分解,Word2Vec 在大规模语料上训练速度更快。
  • 语义捕捉: 能够有效捕捉词语的语义和语法关系。

局限性:

  • 上下文独立 : Word2Vec 为每个词生成固定的向量,无法处理词语的多义性和上下文依赖性
  • 缺乏句子级别表示: 仅对词语进行嵌入,无法直接用于句子或段落的表示。
  • 对未登录词的处理: 无法生成未在词汇表中出现的词语的向量。

应用场景

  1. 词语相似度计算: 通过计算词向量之间的相似度,获取与给定词语语义相近的词。
  2. 文本分类和聚类: 将文本表示为词向量的组合,用于分类或聚类任务。
  3. 机器翻译: 通过训练词向量实现词语间的语义映射,辅助翻译。
  4. 信息检索: 改进搜索引擎的关键词匹配,提升用户查询的匹配质量。
  5. 情感分析: 捕捉文本中情感信息,应用于情绪监控等领域。

改进和扩展

  1. FastText: 将词语分解为字符 n-gram,能够处理未登录词和词语的内部结构。

  2. GloVe (Global Vectors for Word Representation): 结合全局语料词共现信息,利用矩阵分解的方法生成词向量。

  3. ELMo (Embeddings from Language Models): 基于词向量的语言模型,生成上下文敏感的词向量,解决词语的多义性问题。

  4. BERT (Bidirectional Encoder Representations from Transformers): 利用 Transformer 架构,生成深度的上下文表示,可用于句子和段落级别的嵌入。

Word2Vec 是自然语言处理领域的重要里程碑,通过将词语映射到连续向量空间,开创了基于分布式表示的词语语义建模方法。虽然存在一些局限,但模型的后续发展(如 FastText、BERT 等)的发展竞相出现。对于从事 NLP 研究和应用的人员,深入理解 Word2Vec 的原理和实现,有助于更好地应用和改进词向量的建模技术。

二、GloVe

GloVe(Global Vectors for Word Representation)是由斯坦福大学的 Jeffrey Pennington、Richard Socher 和 Christopher D. Manning 于 2014 年提出的一种词向量表示模型。GloVe 的主要思想是结合全局的词共现统计信息与局部的上下文窗口信息,通过矩阵分解的方式,生成能够捕捉词语语义和语法特征的高质量词向量。与基于预测的模型(如 Word2Vec)不同,GloVe 直接利用词语的共现概率,旨在更好地捕捉全局语义关系。

1.基本原理

GloVe 模型的核心思想是:词语的语义关系可以通过词共现概率的比值来捕捉。在大规模语料库中,统计词语之间的共现次数,可以得到一个词共现矩阵。GloVe 利用这个矩阵,通过最小化词向量与共现概率对数之间的差异,学习出词向量表示

词共现矩阵

  • 定义 : 在给定语料库中,统计每个词对 ( ( i , j ) ) ((i,j)) ((i,j)) 共同出现的次数 X i j X_{ij} Xij,形成词共现矩阵 X X X。
  • 共现概率 : 词 j j j 在给定词 i i i 的条件下出现的概率为:

P i j = X i j X i P_{ij} = \frac{X_{ij}}{X_i} Pij=XiXij

其中, X i = ∑ k X i k X_i = \sum_k X_{ik} Xi=∑kXik 是词 i i i 出现时所有共现词的总次数。

损失函数的构建

GloVe 的目标是找到一个映射,使得词向量之间的关系能够反映词语的共现概率。具体来说,模型希望满足以下关系:

w i T w j + b i + b j = log ⁡ ( X i j ) w_i^T w_j + b_i + b_j = \log(X_{ij}) wiTwj+bi+bj=log(Xij)

其中:

  • w i w_i wi 和 w j w_j wj 分别是词 i i i 和词 j j j 的词向量。
  • b i b_i bi 和 b j b_j bj 是对应的偏置项。

为了实现这一目标,GloVe 定义了以下损失函数:

J = ∑ i , j = 1 V f ( X i j ) ( w i T w j + b i + b j − log ⁡ X i j ) 2 J = \sum_{i,j=1}^{V} f(X_{ij}) \left( w_i^T w_j + b_i + b_j - \log X_{ij} \right)^2 J=i,j=1∑Vf(Xij)(wiTwj+bi+bj−logXij)2

其中:

  • V V V 是词汇表的大小。
  • f ( X i j ) f(X_{ij}) f(Xij) 是权重函数,控制不同频次的词对对损失的贡献。

权重函数

为了避免高频词对损失函数的主导,同时又不忽略低频词,GloVe 采用如下的权重函数:

f ( x ) = { ( x x max ) α if x < x max 1 if x ≥ x max f(x) = \begin{cases} \left( \frac{x}{x_{\text{max}}} \right)^\alpha & \text{if } x < x_{\text{max}} \\ 1 & \text{if } x \geq x_{\text{max}} \end{cases} f(x)={(xmaxx)α1if x<xmaxif x≥xmax

常用的参数取值为 α = 0.75 \alpha = 0.75 α=0.75, x max = 100 x_{\text{max}} = 100 xmax=100。


2.训练方法和实践步骤

模型训练步骤

  1. 数据预处理: 对语料库进行分词,去除停用词等预处理操作。
  2. 构建词共现矩阵 : 设定窗口大小 w w w,统计词对共现次数 X i j X_{ij} Xij。
  3. 初始化参数 : 随机初始化词向量 w i w_i wi, w j w_j wj 以及偏置项 b i b_i bi, b j b_j bj。
  4. 定义损失函数 : 使用上述损失函数 J J J。
  5. 优化损失函数 : 采用 AdaGrad 等优化算法,最小化损失函数 J J J。
  6. 获取最终词向量 : 训练完成后,通常将 w i w_i wi 和 w j w_j wj 相加或取平均,作为词 i i i 的最终表示。

优化算法

  • AdaGrad: 自适应学习率优化算法,适合处理稀疏数据和大规模数据集。
  • 并行化: GloVe 的训练过程中可以进行并行化,加速模型的训练。

实践指南

  1. 数据准备
  • 收集语料: 获取大规模、多样性的文本数据集,如维基百科、新闻语料等。
  • 数据预处理: 清除噪声,去除标点、统一大小写等。
  • 分词处理: 对文本进行分词,进行去除停用词操作。
  1. 构建词共现矩阵
  • 设定窗口大小: 通常选择 5 到 10。
  • 统计词共现次数: 统计词对共现次数,并构造词语之间的共现矩阵。
  1. 模型训练
  • 设置超参数: 选择词向量维度(如 50、100、300)、学习率等。
  • 选择优化算法: 选择常用的 AdaGrad 等优化算法。
  • 训练模型: 优化损失函数,最小化目标函数。
  1. 模型评估
  • 相似度测试: 测试词向量之间的余弦相似度是否能反映语义关系上的相近性。
  • 下游任务应用: 在具体任务中进行验证和测试,评估性能表现。

3.python代码实现

python 复制代码
from glove import Corpus, Glove

# 准备语料
sentences = [
    ['我', '喜欢', '自然', '语言', '处理'],
    ['词向量', '是', 'NLP', '的重要', '组成部分'],
    ['GloVe', '模型', '利用', '词共现', '统计信息']
]

# 构建词共现矩阵
corpus = Corpus()
corpus.fit(sentences, window=5)

# 训练 GloVe 模型
glove = Glove(no_components=100, learning_rate=0.05)
glove.fit(corpus.matrix, epochs=20, no_threads=4, verbose=True)
glove.add_dictionary(corpus.dictionary)

# 获取词向量
vector = glove.word_vectors[glove.dictionary['自然']]

# 查找相似词
similar = glove.most_similar('自然', number=5)
print(similar)

4.总结

4.1. 优势和局限性

优势

  • 全局统计信息: 利用全局共现统计信息,能更精确捕捉更丰富的语义关系。
  • 高效性: 在小样本数据的高频训练下表现优秀,内存利用率较高,适用于大规模数据。
  • 稀疏性处理: 能够较好地处理稀疏性信息。

局限性

  • 内存消耗较大: 构建矩阵时内存开销较大,适合离线处理。
  • 上下文独立: 与 Word2Vec 一样,无法处理词语的多义性和上下文变化。
  • 数据依赖: GloVe 依赖于全局的词共现矩阵,无法动态更新词向量。

4.2. 与 Word2Vec 的比较

  • 信息利用方式:

    • Word2Vec: 基于局部上下文的预测,利用滑动窗口中的词语共现信息。
    • GloVe: 结合全局的词共现统计信息,更全面地捕捉词语之间的关系。
  • 模型基本原理:

    • Word2Vec: 属于预测型模型,基于神经网络。
    • GloVe: 属于基于计数的模型,进行矩阵分解。
  • 训练效率:

    • Word2Vec: 在大规模语料上训练速度较快,但需要高频迭代多个训练次数。
    • GloVe: 预先构造词共现矩阵,训练次数较少但构造成本高。
  • 性能差异:

    • 词类比任务: 两者性能相近,GloVe 有时表现更好。
    • 计算复杂性: GloVe 由于依赖共现矩阵,Word2Vec 更节省内存。

4.3. 应用场景

  • 词语相似度计算: 评估词语之间的相似性和关联性。
  • 文本分类和聚类: 将文本表示为词向量的组合,用于分类或聚类任务。
  • 机器翻译: 通过捕捉语义关系,辅助机器翻译任务。
  • 信息检索和问答系统: 改进搜索结果的相关性,提升用户体验。
  • 情感分析: 捕捉文本中的情感倾向,应用于舆情监控等领域。

GloVe 模型通过融合全局的词共现统计信息,为词向量表示提供了强有力的工具。它在捕捉词语的语义和语法关系方面表现出色,已成为自然语言处理领域的重要方法之一。尽管存在内存需求大、无法处理上下文等局限,但通过改进和扩展,GloVe 仍具有广阔的应用前景。深入理解 GloVe 的原理和实现,有助于更好地应用词向量技术,解决实际的 NLP 问题。

三、FastText

FastText 是由 Facebook 的研究团队于 2016 年提出的一种用于高效学习词向量和文本分类的模型。它在 Word2Vec 的基础上进行了改进,能够处理未登录词(out-of-vocabulary words)和捕捉词语内部的形态信息。FastText 将每个词表示为字符 n-gram 的集合,从而可以更好地捕捉词的拼写和形态学特征,特别适用于处理大量的词汇和罕见词。

1.基本原理

  1. 词表示方式

FastText 的核心思想是将每个词表示为其字符 n-gram 的集合,并将词本身也视为一个特殊的 n-gram。具体来说:

  • 字符 n-gram : 将一个词分解为所有可能的 n-gram,通常 n n n 的取值范围为 3 到 6。
  • 词的表示: 一个词的向量表示是其所有 n-gram 向量的和或平均。

示例:

对于词 "apple",取 n = 3 n=3 n=3,则其字符 3-gram 有:

  • <ap, app, ppl, ple, le>

这里,<> 分别表示词的开始和结束。

2.模型结构

FastText 的模型架构与 Word2Vec 的 Skip-Gram 模型类似,但在输入层处理上有所不同:

  • 输入层: 词由字符 n-gram 的集合表示。
  • 隐藏层: 将 n-gram 向量投影到隐藏层。
  • 输出层 : 通过 softmax 或近似方法,预测上下文词

FastText 旨在最大化输入词与上下文词之间的共现概率。其损失函数与 Skip-Gram 模型类似,但在词向量表示上使用了 n-gram 的集合。

3.训练方法和实践步骤

3.1. 模型训练

  1. 数据预处理
  • 分词: 将语料库切分为词词序列。
  • 生成 n-gram: 对于每个词,生成对应的字符 n-gram 集合。
  1. 训练过程
  • 输入表示: 对于中心词,获取其所有的字符 n-gram,并查找对应的 n-gram 向量。
  • 上下文预测: 利用中心词的 n-gram 向量,预测上下文词的概率分布。
  • 优化目标: 最小化负对数似然损失,或使用负采样进行高效训练。
  1. 采用优化技术
  • 负采样 (Negative Sampling): 减少计算复杂度,提高清训练速度。
  • 分层 softmax (Hierarchical Softmax): 对大型词汇表进行高效的概率计算。

4.python代码实现

使用 Python 接口

python 复制代码
import fasttext

# 训练词向量模型
model = fasttext.train_unsupervised('corpus.txt', model='skipgram', dim=100, minn=3, maxn=6)

# 获取词向量
vector = model.get_word_vector('自然语言处理')

# 查找相似词
similar_words = model.get_nearest_neighbors('自然语言处理', k=5)
print(similar_words)

文本分类示例

python 复制代码
import fasttext

# 训练文本分类模型
model = fasttext.train_supervised('train.txt', label_prefix='__label__', epoch=5, lr=0.1)

# 模型评估
result = model.test('test.txt')
print('Precision:', result.precision)
print('Recall:', result.recall)

# 预测新样本
labels, probabilities = model.predict('这是一个新的评论', k=2)
print(labels, probabilities)

5.总结

优势

  1. 处理未登录词

由于 FastText 使用了字符 n-gram,当遇到未出现在训练集中出现的词时,仍然可以通过其字符 n-gram 获取词向量。这使得模型在处理罕见词或新词时表现更佳。

  1. 捕捉词形信息

字符 n-gram 能够捕捉到前缀、后缀和词根等信息,处理形态丰富的语言(如法语、德语等)尤为有利。

  1. 高效性

FastText 在保持高性能的同时,具有较快的训练速度和较低的内存占用,适合大规模数据训练。

应用场景

  1. 词向量表示
  • 语义相似度计算:获取词语的向量表示,计算词语之间的相似度。
  • 文本表示:将句子或文档表示为词向量的组合,用于各种 NLP 任务。
  1. 文本分类
  • 监督学习:FastText 提供了高效的文本分类算法,适用于情感分析、主题分类等任务。
  • 多语言支持:在多语言环境下,FastText 能够高效处理多种语言的文本分类。
  1. 命名实体识别和词性标注
  • 利用词的形态特征:通过字符 n-gram,模型能够更好地识别词的类型和特征。

FastText 通过引入字符 n-gram,将词的内部结构纳入模型,有效地解决了未登录词和低频词的表示问题。其高效性和易用性使其在自然语言处理的多个领域得到了广泛应用。对于需要处理大量文本数据的任务,FastText 是一个强大的工具。通过深入理解其原理和实践方法,能够更好地应用 FastText,提高 NLP 模型的性能。

四、对比总结

特性 Word2Vec GloVe FastText
训练原理 基于局部上下文窗口 基于全局词共现矩阵 基于局部上下文窗口 + 子词信息
处理多义词 无法处理 无法处理 有一定能力处理(基于子词)
未见词处理 无法处理 无法处理 可以通过子词 n-grams 处理
计算效率 高效(负采样) 计算复杂度较高 训练相对慢,但推理时效率高
语义捕捉能力 强(依赖上下文) 强(依赖全局信息) 较弱,特别适合低资源语言
适用场景 适合大规模语料,常见语言 适合大规模语料,需要全局语义的场景 适合多语言任务,低资源语言或未见词场景
  • Word2Vec 适合在大规模语料上快速训练词向量,能够很好地捕捉词的局部语义关系,但对多义词和未见词无能为力。
  • GloVe 则侧重于全局的语料统计信息,适合需要全局语义关系的任务,然而其计算代价较高且在未见词处理方面存在局限。
  • FastText 通过子词的 n-grams 技术,能很好地处理形态丰富语言和未见词问题,是一个兼顾效率和表现的改进模型。

结~~~

相关推荐
Fuxiao___8 分钟前
不使用递归的决策树生成算法
算法
我爱工作&工作love我13 分钟前
1435:【例题3】曲线 一本通 代替三分
c++·算法
学术搬运工39 分钟前
【珠海科技学院主办,暨南大学协办 | IEEE出版 | EI检索稳定 】2024年健康大数据与智能医疗国际会议(ICHIH 2024)
大数据·图像处理·人工智能·科技·机器学习·自然语言处理
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
workflower1 小时前
数据结构练习题和答案
数据结构·算法·链表·线性回归
好睡凯1 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法
Sunyanhui11 小时前
力扣 二叉树的直径-543
算法·leetcode·职场和发展
一个不喜欢and不会代码的码农1 小时前
力扣105:从先序和中序序列构造二叉树
数据结构·算法·leetcode
前端郭德纲1 小时前
浏览器是加载ES6模块的?
javascript·算法
SoraLuna1 小时前
「Mac玩转仓颉内测版10」PTA刷题篇1 - L1-001 Hello World
算法·macos·cangjie