Skip to main content

核心认知

数组是一种线性数据结构,它最重要的特征不是“按顺序排好”,而是:
  • 元素通常连续存储
  • 可以通过下标直接访问
这两个特征决定了数组题特别适合用:
  • 下标
  • 双指针
  • 滑动窗口
  • 前缀和

数组在内存中的样子

数组内存布局示意 这张图最重要的信息只有两个:
  • 元素是连续存放的
  • 下标本质上是在定位这段连续空间里的第几个位置
所以数组题里很多“查得快”的前提,其实就是你能通过下标直接定位到对应元素。

为什么数组题总是第一章

因为数组是最容易建立“下标思维”的结构。 你在数组里做的每一次移动、比较、覆盖,其实都在训练后面做题最重要的基本功:
  • 区间怎么表示
  • 左右边界怎么维护
  • 原地修改怎么实现

数组和链表有什么区别

数组最突出的优势是查询快。
nums = [10, 20, 30, 40]
print(nums[2])  # 30
你只要知道下标,就能立刻取到元素。
但如果你想在中间插入或删除一个元素,就往往要整体移动后面的内容。
所以通常可以这样记:
  • 数组适合查
  • 链表适合改

数组题为什么常出现双指针

因为数组有天然的“位置”概念。 你可以让两个指针分别表示:
  • 当前有效区间
  • 左右边界
  • 快慢指针
  • 头尾夹逼
例如删除指定元素:
def remove_element(nums: list[int], target: int) -> int:
    slow = 0
    for fast in range(len(nums)):
        if nums[fast] != target:
            nums[slow] = nums[fast]
            slow += 1
    return slow
这里的关键不是“删除”,而是把满足条件的元素重新压缩到数组前面。

常见题型

数组题通常会反复出现这几类模型:
  • 二分查找
  • 快慢指针
  • 左右指针
  • 滑动窗口
  • 前缀和
  • 模拟
很多题表面不一样,但本质就是在数组上维护一个区间。

一个最值得会写的 Python 例子

滑动窗口是数组题里非常高频的模型。
def min_sub_array_len(target: int, nums: list[int]) -> int:
    left = 0
    current_sum = 0
    answer = float("inf")

    for right, value in enumerate(nums):
        current_sum += value

        while current_sum >= target:
            answer = min(answer, right - left + 1)
            current_sum -= nums[left]
            left += 1

    return 0 if answer == float("inf") else answer
你可以把这个模板理解成:
  • right 负责扩张区间
  • left 负责收缩区间
  • 中间不断维护答案

学习建议

如果你刚开始学数组,建议按这个顺序练:
  • 二分查找
  • 删除元素
  • 有序数组去重
  • 长度最小的子数组
  • 螺旋矩阵
当你习惯先定义“区间”和“边界”时,数组题会变得非常顺。