【笔面试算法学习专栏】双指针专题:简单难度三题精讲(167.两数之和II、283.移动零、344.反转字符串)

1. 引言与双指针基础

双指针算法是解决数组、字符串、链表等线性数据结构问题的核心优化技巧。通过在数据遍历过程中维护两个指针(索引),以不同速度、方向或策略协同工作,能将暴力解法的 O ( n 2 ) O(n^2) O(n2) 时间复杂度优化至 O ( n ) O(n) O(n),同时常实现 O ( 1 ) O(1) O(1) 的空间复杂度。这一技巧在力扣hot100、算法面试中高频出现,是必须掌握的基础算法范式。

1.1 三种主要类型及应用场景

1. 对撞指针(Two Pointers)

  • 指针移动:一个指针从起始位置开始,另一个从末尾开始,向中间靠拢
  • 适用场景
    • 有序数组查找:两数之和II、三数之和、最接近的三数之和
    • 反转问题:反转字符串、验证回文串
    • 容器问题:盛最多水的容器
  • 时间复杂度 : O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1)

2. 快慢指针(Fast & Slow Pointers)

  • 指针移动:快指针每次移动两步(或更快),慢指针每次移动一步
  • 适用场景
    • 链表问题:环检测、中间节点、相交链表
    • 原地修改:移动零、删除排序数组重复项、移除元素
  • 时间复杂度 : O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1)

3. 滑动窗口(Sliding Window)

  • 指针移动:维护左右边界定义的窗口,动态调整窗口大小
  • 适用场景
    • 子字符串问题:无重复字符最长子串、最小覆盖子串
    • 子数组问题:长度最小子数组、最大连续1的个数
  • 时间复杂度 : O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1) 或 O ( k ) O(k) O(k)

1.2 算法优势与核心思想

  1. 时间复杂度优化 :避免双重循环,将 O ( n 2 ) O(n^2) O(n2) 降至 O ( n ) O(n) O(n)
  2. 空间复杂度优化 :通常只需 O ( 1 ) O(1) O(1) 额外空间,实现原地操作
  3. 逻辑清晰简洁:指针移动条件明确,代码易于理解和维护
  4. 适用性广泛:覆盖数组、字符串、链表等多种数据结构

注:双指针并非独立的算法分类,而是一种优化技巧(或称编程范式)。它常与二分查找、贪心算法、动态规划等经典算法结合使用,核心思想是通过指针的巧妙移动减少不必要的计算,缩小搜索空间。

1.3 本文内容安排

本文将深入解析三道力扣hot100简单难度题目,系统讲解对撞指针和快慢指针的应用:

  • 167.两数之和II:对撞指针经典应用,利用有序性高效查找
  • 283.移动零:快慢指针原地修改,保持元素相对顺序
  • 344.反转字符串 :对撞指针对称交换,实现 O ( 1 ) O(1) O(1) 空间复杂度

每道题目提供完整分析:题目概述、核心思路、复杂度证明、Python实现及优化讨论,帮助读者建立双指针算法的系统性认知。

2. 167.两数之和II-输入有序数组

2.1 题目概述

题目链接167. Two Sum II - Input Array Is Sorted

问题描述

给定一个已按照非递减顺序排列 的整数数组 numbers,从数组中找出两个数满足相加之和等于目标数 target。假设每个输入只对应唯一的答案,且数组中同一个元素不能使用两遍。返回这两个数的下标值(下标值以 1 为起始)。

示例

复制代码
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于 9,因此 index1 = 1, index2 = 2。

约束条件

  • 2 ≤ numbers.length ≤ 3 × 10 4 2 \le \text{numbers.length} \le 3 \times 10^4 2≤numbers.length≤3×104
  • − 1000 ≤ numbers[i] ≤ 1000 -1000 \le \text{numbers[i]} \le 1000 −1000≤numbers[i]≤1000
  • 数组按非递减顺序排列
  • − 1000 ≤ target ≤ 1000 -1000 \le \text{target} \le 1000 −1000≤target≤1000
  • 测试用例保证有且仅有一个有效答案

2.2 核心解题思路:对撞指针

暴力解法分析

最直接的思路是双重循环遍历所有可能的数对,检查其和是否等于 target。时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为 O ( 1 ) O(1) O(1)。对于长度可达 3 × 10 4 3 \times 10^4 3×104 的数组, O ( n 2 ) O(n^2) O(n2) 的算法会超时。

对撞指针优化

利用数组已排序的特性,使用对撞指针将时间复杂度优化到 O ( n ) O(n) O(n):

  1. 指针初始化

    • left = 0(指向数组起始)
    • right = len(numbers) - 1(指向数组末尾)
  2. 循环条件while left < right

  3. 指针移动策略

    • 计算当前和:current_sum = numbers[left] + numbers[right]
    • current_sum == target:找到答案,返回 [left+1, right+1]
    • current_sum < target:当前和太小,需要增大,left 右移(left += 1
    • current_sum > target:当前和太大,需要减小,right 左移(right -= 1

正确性证明

  • 单调性保证 :数组按非递减顺序排列,即 numbers[left] ≤ numbers[left+1]numbers[right-1] ≤ numbers[right]
  • 完整性保证 :每次移动指针都会排除一部分不可能的解:
    • current_sum < target 时,对于固定的 rightnumbers[left]numbers[left+1]...numbers[right] 的组合都不可能等于 target(因为最小的 numbers[left] 已经太小)
    • current_sum > target 时,对于固定的 leftnumbers[left]numbers[left]...numbers[right-1] 的组合都不可能等于 target(因为最大的 numbers[right] 已经太大)
  • 收敛性保证 :每次迭代 right - left 严格减小,最终必然相遇或找到解

注:题目要求下标从1开始,因此返回时需要将 leftright 分别加1。这是力扣题目常见的细节要求,面试时需特别注意。循环条件必须使用 left < right,不能使用 left <= right,以避免使用同一元素两次。

2.3 时间复杂度与空间复杂度分析

时间复杂度 : O ( n ) O(n) O(n)

  • 最坏情况下,leftright 指针从两端向中间移动,总共移动 n − 1 n-1 n−1 次
  • 每次迭代执行常数时间操作(计算和、比较、移动指针)
  • 因此总时间复杂度为 O ( n ) O(n) O(n)

空间复杂度 : O ( 1 ) O(1) O(1)

  • 只使用了常数个额外变量(leftrightcurrent_sum
  • 没有使用与输入规模相关的额外数据结构

算法效率

  • 相比于暴力解法的 O ( n 2 ) O(n^2) O(n2),对撞指针的 O ( n ) O(n) O(n) 算法性能提升显著
  • 对于 n = 30000 n=30000 n=30000 的数组,暴力解法需要约 4.5 × 10 8 4.5 \times 10^8 4.5×108 次操作,而对撞指针只需约 30000 30000 30000 次操作,相差约 15000 15000 15000 倍

2.4 Python代码

python 复制代码
from typing import List

def twoSum(numbers: List[int], target: int) -> List[int]:
    left, right = 0, len(numbers) - 1
    while left < right:
        current_sum = numbers[left] + numbers[right]
        if current_sum == target:
            return [left + 1, right + 1]
        elif current_sum < target:
            left += 1
        else:
            right -= 1
    return [-1, -1]  # 题目保证有解,不会执行

注:循环条件 left < right 确保不使用同一元素,下标加1满足题目要求。

2.5 优化与变式

二分查找 : O ( n log ⁡ n ) O(n \log n) O(nlogn),代码更简单。
哈希表 : O ( n ) O(n) O(n) 时间, O ( n ) O(n) O(n) 空间,适用于无序数组。
三数之和:固定一数,对撞指针找另外两数,需去重处理。

3. 283.移动零

3.1 题目概述

题目链接283. Move Zeroes

问题描述

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。必须在原数组上操作,不能拷贝额外的数组,尽量减少操作次数。

示例

复制代码
输入:nums = [0,1,0,3,12]
输出:[1,3,12,0,0]

约束条件

  • 1 ≤ nums.length ≤ 10 4 1 \le \text{nums.length} \le 10^4 1≤nums.length≤104
  • − 2 31 ≤ nums[i] ≤ 2 31 − 1 -2^{31} \le \text{nums[i]} \le 2^{31} - 1 −231≤nums[i]≤231−1

进阶:你能尽量减少完成的操作次数吗?

3.2 核心解题思路:快慢指针

问题分析

题目要求将所有零移动到数组末尾,同时保持非零元素的相对顺序。关键约束是原地修改 (不能使用额外数组)且要最小化操作次数

暴力解法分析

一种朴素思路是遇到0时,将其后的所有元素向前移动一位,在末尾补0。这种方法时间复杂度为 O ( n 2 ) O(n^2) O(n2)(每个0可能需要移动 O ( n ) O(n) O(n) 个元素),操作次数过多,不符合要求。

快慢指针优化

使用快慢指针可以在 O ( n ) O(n) O(n) 时间内完成操作,且操作次数最优:

方法一:两次遍历法(复制+补零)

  1. 慢指针 slow:指向下一个非零元素应该放置的位置
  2. 快指针 fast:遍历整个数组,寻找非零元素
  3. 算法步骤
    • 初始化 slow = 0
    • 遍历数组,fast 从0到 len(nums)-1
      • 如果 nums[fast] != 0:将 nums[fast] 复制到 nums[slow],然后 slow += 1
    • 遍历结束后,slow 之前的位置都是非零元素,且保持了原始顺序
    • slow 到数组末尾的所有位置设为0

方法二:一次遍历法(交换)

  • 优化版本,通过交换操作在一次遍历中完成:
    • slow 指向下一个非零元素应该放置的位置
    • fast 遍历数组寻找非零元素
    • nums[fast] != 0 时:交换 nums[slow]nums[fast],然后 slow += 1
    • 零元素被逐渐"推"到数组末尾

正确性证明

  • 顺序保持:快指针按顺序遍历,遇到非零元素就复制/交换到慢指针位置,因此非零元素的相对顺序不变
  • 零元素处理:交换法直接在一次遍历中将零元素逐渐"推"到数组末尾;复制+补零法则先收集所有非零元素,再统一补零
  • 操作次数最小化 :每个非零元素最多被移动一次(交换或复制),零元素可能被多次交换但总操作次数为 O ( n ) O(n) O(n)

注:使用交换法时,当 fast == slownums[fast] != 0,元素会和自己交换,这是不必要的操作。可以通过添加判断条件 if fast != slow 来优化,减少少量赋值操作。但算法复杂度不变,仍是 O ( n ) O(n) O(n)。

3.3 时间复杂度与空间复杂度分析

两次遍历法

  • 时间复杂度 : O ( n ) O(n) O(n)
    • 第一次遍历移动非零元素: O ( n ) O(n) O(n)
    • 第二次遍历补零: O ( n ) O(n) O(n)
    • 总时间: O ( 2 n ) = O ( n ) O(2n) = O(n) O(2n)=O(n)
  • 空间复杂度 : O ( 1 ) O(1) O(1)
    • 只使用常数个额外变量

一次遍历(交换)法

  • 时间复杂度 : O ( n ) O(n) O(n)
    • 只遍历数组一次,每次迭代执行常数时间操作
  • 空间复杂度 : O ( 1 ) O(1) O(1)
    • 只使用常数个额外变量

操作次数比较

  • 两次遍历法:非零元素移动一次(复制),零元素移动一次(赋值)
  • 一次遍历法:每个非零元素最多交换一次(可能包含自我交换)
  • 实际选择:一次遍历法代码更简洁,推荐使用

3.4 Python代码

python 复制代码
from typing import List

def moveZeroes(nums: List[int]) -> None:
    # 一次遍历交换法
    slow = 0
    for fast in range(len(nums)):
        if nums[fast] != 0:
            nums[slow], nums[fast] = nums[fast], nums[slow]
            slow += 1

注:添加 if fast != slow 判断可避免自我交换,减少不必要操作。

3.5 优化与变式

避免自我交换 :判断 fast != slow 后再交换。
移除元素 :类似逻辑,移除等于 val 的元素。
颜色分类:三指针法处理0、1、2排序。

4. 344.反转字符串

4.1 题目概述

题目链接344. Reverse String

问题描述

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。你必须原地修改输入数组,使用 O ( 1 ) O(1) O(1) 的额外空间解决这一问题。

示例

复制代码
输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]

约束条件

  • 1 ≤ s.length ≤ 10 5 1 \le \text{s.length} \le 10^5 1≤s.length≤105
  • s[i] 都是 ASCII 码表中的可打印字符

进阶

  • 不要给另外的数组分配额外的空间,你必须原地修改输入数组
  • 使用 O ( 1 ) O(1) O(1) 的额外空间解决这一问题

4.2 核心解题思路:对撞指针

问题分析

题目要求原地反转字符数组,即第一个字符与最后一个字符交换,第二个字符与倒数第二个字符交换,依此类推。关键约束是原地修改 且只能使用** O ( 1 ) O(1) O(1)额外空间**。

暴力解法分析

最直接的思路是创建一个新数组,从后向前复制元素。但这违反了原地修改的要求,且空间复杂度为 O ( n ) O(n) O(n),不符合题目要求。

对撞指针优化

使用对撞指针可以在 O ( n ) O(n) O(n) 时间内原地完成反转:

  1. 指针初始化

    • left = 0:指向数组开头
    • right = len(s) - 1:指向数组末尾
  2. 算法步骤

    • while left < right
      • 交换 s[left]s[right]
      • left += 1
      • right -= 1
  3. 终止条件分析

    • 当字符串长度为奇数时,中间元素不需要交换(left == right
    • 当字符串长度为偶数时,所有元素都完成交换(left > right
    • 因此循环条件为 left < right

正确性证明

  • 对称性:每次迭代交换对称位置的两个字符
  • 完整性:从外向内逐对交换,直到中心位置
  • 原地性:只使用交换操作,不需要额外数组
  • 收敛性 :每次迭代 left 增加,right 减少,最终 left >= right

注:Python中字符串是不可变对象,但题目输入是字符列表(List[str]),可以直接修改。在实际编程中,如果输入是真正的字符串,需要先转换为列表,反转后再转换为字符串,但这会增加 O ( n ) O(n) O(n) 的空间开销。本题明确输入是字符数组,因此可以直接操作。

4.3 时间复杂度与空间复杂度分析

时间复杂度 : O ( n ) O(n) O(n)

  • 需要交换 ⌊ n / 2 ⌋ \lfloor n/2 \rfloor ⌊n/2⌋ 对字符
  • 每次交换执行常数时间操作(赋值、增减指针)
  • 因此总时间复杂度为 O ( n ) O(n) O(n)

空间复杂度 : O ( 1 ) O(1) O(1)

  • 只使用了常数个额外变量(leftright、临时交换变量)
  • 完全符合题目要求的 O ( 1 ) O(1) O(1) 额外空间

操作次数详细分析

  • 总交换次数: ⌊ n / 2 ⌋ \lfloor n/2 \rfloor ⌊n/2⌋ 次
  • 每次交换:3次赋值操作(使用临时变量)或元组解包(内部实现类似)
  • 指针操作:leftright 各增减 ⌊ n / 2 ⌋ \lfloor n/2 \rfloor ⌊n/2⌋ 次
  • 总赋值次数:约 3 × ⌊ n / 2 ⌋ = O ( n ) 3 \times \lfloor n/2 \rfloor = O(n) 3×⌊n/2⌋=O(n)

4.4 Python代码

python 复制代码
from typing import List

def reverseString(s: List[str]) -> None:
    left, right = 0, len(s) - 1
    while left < right:
        s[left], s[right] = s[right], s[left]
        left += 1
        right -= 1

注:Python元组解包交换简洁高效,实际使用临时元组但空间复杂度仍为 O ( 1 ) O(1) O(1)。

4.5 优化与变式

递归解法 :交换首尾后递归处理子串,但栈空间 O ( n ) O(n) O(n)。
反转单词 :定位单词边界,分别反转。
旋转数组:三次反转法实现右旋k位。

5. 总结与面试考点

5.1 双指针算法核心思想总结

通过本文对三道简单难度双指针题目的深入分析,我们可以系统总结双指针算法的核心思想与应用模式:

1. 对撞指针(Two Pointers)

  • 核心机制:指针从数组/字符串两端向中间移动,每次迭代根据比较结果移动其中一个指针
  • 适用场景
    • 有序数组查找:两数之和、三数之和、最接近的三数之和
    • 反转问题:反转字符串、验证回文串
    • 容器问题:盛最多水的容器
  • 时间复杂度 : O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1)
  • 关键技巧:利用数据有序性,每次移动排除一半不可能解

2. 快慢指针(Fast & Slow Pointers)

  • 核心机制:快指针以更快速度(通常为两步)移动,慢指针以正常速度(一步)移动
  • 适用场景
    • 链表问题:环检测、中间节点、相交链表
    • 原地修改:移动零、删除排序数组重复项、移除元素
  • 时间复杂度 : O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1)
  • 关键技巧:通过速度差定位特定位置或实现原地修改

3. 滑动窗口(Sliding Window)

  • 核心机制:维护左右边界定义的动态窗口,根据条件调整窗口大小
  • 适用场景
    • 子字符串问题:无重复字符最长子串、最小覆盖子串
    • 子数组问题:长度最小子数组、最大连续1的个数
  • 时间复杂度 : O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1) 或 O ( k ) O(k) O(k)
  • 关键技巧:通过窗口扩张和收缩寻找满足条件的极值

5.2 时间复杂度优化策略与性能分析

双指针算法的主要优势在于显著的时间复杂度优化:

1. O ( n 2 ) → O ( n ) O(n^2) → O(n) O(n2)→O(n) 的降维优化

  • 两数之和 :暴力双重循环 O ( n 2 ) O(n^2) O(n2) → 对撞指针 O ( n ) O(n) O(n),性能提升 O ( n ) O(n) O(n) 倍
  • 移动零 :暴力移位 O ( n 2 ) O(n^2) O(n2) → 快慢指针 O ( n ) O(n) O(n),性能提升 O ( n ) O(n) O(n) 倍
  • 性能对比 :对于 n = 10000 n=10000 n=10000 的数组,暴力解法需要约 10 8 10^8 108 次操作,双指针只需 10 4 10^4 104 次操作,相差 10 4 10^4 104 倍

2. O ( n ) → O ( 1 ) O(n) → O(1) O(n)→O(1) 的空间优化

  • 反转字符串 :额外数组 O ( n ) O(n) O(n) 空间 → 对撞指针 O ( 1 ) O(1) O(1) 空间
  • 原地修改:避免创建新数据结构,降低内存占用
  • 实际意义:在大数据场景下,空间优化与时间优化同等重要

3. 算法效率的数学证明

  • 对撞指针 :每次迭代排除至少一个不可能解, n n n 次迭代内必然找到解或遍历完
  • 快慢指针 :快指针比慢指针快一倍, n n n 步内快指针必然遍历完或检测到环
  • 收敛性保证:所有双指针算法都满足单调收敛条件,确保算法终止

5.3 面试常见考点与应对策略

1. 基础概念理解类问题

  • 典型问题
    • "双指针算法有哪几种类型?各自适用什么场景?"
    • "对撞指针和快慢指针的时间复杂度分别是多少?如何证明?"
    • "滑动窗口算法的核心思想是什么?"
  • 应对策略
    • 清晰分类:对撞、快慢、滑动窗口三大类
    • 举例说明:每类给出2-3个经典力扣题目
    • 复杂度分析:结合数学公式和具体证明

2. 代码实现能力类问题

  • 典型问题
    • "手写两数之和的对撞指针解法"
    • "实现移动零的快慢指针算法"
    • "处理边界条件:空数组、单元素、全零等特殊情况"
  • 应对策略
    • 模版化代码:掌握核心代码结构
    • 边界测试:显式测试各种边界情况
    • 代码优化:减少不必要的操作和变量

3. 问题变式分析类问题

  • 典型问题
    • "如果数组无序,两数之和问题如何解决?"
    • "如果需要保持零元素的相对顺序,移动零问题如何修改?"
    • "如果字符串包含中文(多字节字符),反转字符串需要注意什么?"
  • 应对策略
    • 算法转换:哈希表解决无序两数之和
    • 条件修改:快慢指针保持相对顺序
    • 编码处理:考虑Unicode多字节字符特性

4. 算法扩展思考类问题

  • 典型问题
    • "双指针算法与二分查找、贪心算法、动态规划的关系是什么?"
    • "双指针算法能否用于二维数组或图结构?"
    • "双指针算法在分布式系统或数据库查询中有哪些应用?"
  • 应对策略
    • 算法对比:分析异同点和适用场景
    • 结构扩展:讨论在复杂数据结构中的应用可能
    • 实际应用:结合系统设计和工程实践

5.4 面试准备建议与学习路径

1. 核心技能掌握

  • 必会题目
    • 对撞指针:167.两数之和II、15.三数之和、11.盛最多水的容器
    • 快慢指针:283.移动零、26.删除排序数组重复项、141.环形链表
    • 滑动窗口:3.无重复字符最长子串、76.最小覆盖子串、209.长度最小子数组
  • 掌握程度:每题能够独立完成,理解算法原理,处理边界情况

2. 编码能力训练

  • 关键要点
    • 指针初始化:正确设置起始和结束位置
    • 循环条件:使用 while left < right 而非 while left <= right
    • 交换操作:掌握元组解包和临时变量两种方式
    • 代码简洁:避免冗余变量和操作
  • 实践方法:在力扣平台反复练习,追求一次通过

3. 变式问题准备

  • 准备方向
    • 同一问题的不同约束条件
    • 相似问题的双指针解法差异
    • 双指针与其他算法的结合应用
  • 学习资源:力扣专题、算法书籍、技术博客

4. 进阶学习路径

  • 困难题目
    • 42.接雨水:对撞指针的复杂应用
    • 76.最小覆盖子串:滑动窗口的高级技巧
    • 239.滑动窗口最大值:单调队列与双指针结合
  • 相关领域
    • 二分查找:有序数组的快速定位
    • 贪心算法:局部最优导致全局最优
    • 动态规划:状态转移与最优子结构
  • 实际应用
    • 数据库查询优化:双指针合并有序结果
    • 系统设计:滑动窗口限流算法
    • 机器学习:特征选择与数据预处理

5.5 本文内容回顾与学习价值

本文通过三道力扣hot100简单难度题目,系统讲解了双指针算法的核心思想与应用:

1. 167.两数之和II-输入有序数组

  • 展示了对撞指针在有序数组中的应用
  • 将时间复杂度从 O ( n 2 ) O(n^2) O(n2) 优化到 O ( n ) O(n) O(n)
  • 关键技巧:利用单调性,每次移动排除不可能解

2. 283.移动零

  • 展示了快慢指针在数组原地修改中的应用
  • 保持了非零元素的相对顺序
  • 关键技巧:通过交换或复制实现零元素后移

3. 344.反转字符串

  • 展示了对撞指针在字符串反转中的应用
  • 实现了 O ( 1 ) O(1) O(1) 的空间复杂度
  • 关键技巧:对称位置字符交换

学习价值

  1. 系统性认知:从基础概念到高级应用,建立完整知识体系
  2. 实战导向:每道题目提供完整分析、代码实现及优化讨论
  3. 面试准备:涵盖常见考点、应对策略和学习路径
  4. 技术深度:深入算法原理、复杂度分析和正确性证明

后续学习建议

  1. 巩固基础:熟练掌握本文三道题目,达到举一反三
  2. 拓展练习:完成对撞指针、快慢指针、滑动窗口的进阶题目
  3. 系统学习:结合算法书籍和在线课程,深入算法理论
  4. 实战应用:在项目开发中应用双指针思想解决实际问题

双指针算法是算法面试中的高频考点,也是解决实际工程问题的重要工具。通过系统学习和反复练习,掌握其核心思想和应用技巧,能够显著提升算法能力和面试表现,为职业发展打下坚实基础。

相关推荐
Book思议-2 小时前
【数据结构】数组与特殊矩阵
数据结构·算法·矩阵
不吃蘑菇!2 小时前
LeetCode Hot 100-1(两数之和)
java·数据结构·算法·leetcode·哈希表
paeamecium2 小时前
【PAT甲级真题】- Linked List Sorting (25)
数据结构·c++·算法·pat考试·pat
小江的记录本2 小时前
【Spring注解】Spring生态常见注解——面试高频考点总结
java·spring boot·后端·spring·面试·架构·mvc
AnalogElectronic2 小时前
uniapp学习6,滚动字幕播报
javascript·学习·uni-app
phoenixlxl2 小时前
allegro导出焊盘
学习
96772 小时前
C++ Lambda 表达式 匿名函数 sort
数据结构·c++·算法
艾莉丝努力练剑2 小时前
【Linux信号】Linux进程信号(下):可重入函数、Volatile关键字、SIGCHLD信号
linux·运维·服务器·c++·人工智能·后端·学习
codeの诱惑2 小时前
推荐算法(二):核心概念——余弦定理 & 余弦相似度
算法·机器学习·推荐算法