跳到主要内容

笔记

数组与哈希

模式速查表

如果问题提到了…思考…
重复 / 频率计数哈希表 / Counter
“我们是否已经见过?”哈希表 / 集合
范围和预缀和 (1D 或 2D)
O(n²) 暴力法哈希 / 预缀和 / 排序
组队带有键的哈希表 (通常是排序 / 元组)
“原地”两个指针 / 交换
最大 / 最小利润 / 分数贪心 / 运行的最小 / 最大
恒定时间查询预处理 (预缀,哈希表)
子数组 / 窗口滑动窗口 + 哈希表 / 集合
“连续” 值集合 + O(1) 查找

如何思考数组和哈希问题

即使问题看起来很复杂,但许多问题都可以简化为 对数组进行一次或两次遍历,加上某种 辅助结构(哈希表、预缀和等)。

你可能会看到很多:

  • 对 1D 列表进行单次或两次遍历的解决方案
  • 巧妙地使用哈希表 / 集合来避免嵌套循环
  • 排序来分组或排序元素
  • 简单的构建块在更复杂的程序中重复使用

排序也经常出现,例如:

  • 归并排序 – 例如 “排序数组” (LC 912)
  • 原地排序 – 例如 “排序颜色” (LC 75)
  • 桶 / 计数风格方法 – 例如 “Top K 频繁元素” (LC 347)

核心技术

以下是你掌握数组和哈希的常用工具:

  1. 预缀和技术

    • 构建预缀和 / 乘积或后缀数组,以回答范围查询或避免重复计算。
    • 示例:数组形式:除了自身之外 (LC 238) 使用预缀和和后缀乘积而不是除法,在 O(n) 时间和 O(1) 额外空间内(不包括输出)。
  2. 使用哈希表 / 集合来降低复杂性 当你想要:

    • 跟踪计数或频率
    • 在平均 O(1) 时间内检查成员
    • 避免多次扫描数组

    经典问题:

    • Contains Duplicate (LC 217) – 使用集合来检测重复项。
    • Valid Sudoku (LC 36) – 使用每行 / 每列 / 盒子的哈希集合。
    • Group Anagrams (LC 49) – 使用一个签名(排序字符串或字母计数)作为哈希表,将单词映射到列表。
    • Longest Consecutive Sequence (LC 128) – 将所有内容放入集合中,然后在“序列开始”时仅开始计数。
  3. 多数元素模式

    • 识别何时某个东西“出现超过 n/2 次”或“出现超过 n/3 次”。
    • 基本:Majority Element (LC 169) – 使用 Boyer–Moore 投票算法,在 O(n) 时间和 O(1) 空间内。
    • 变体模式也出现在更高级的问题中。
  4. 二维数组 / 矩阵 + 预缀和

    • 将矩阵视为数组的 2D 扩展。
    • 预先计算 2D 预缀和,以在 O(1) 时间内回答子矩阵查询,并在 O(m·n) 预处理后。
    • 示例:Range Sum Query 2D – Immutable (LC 304)。
  5. 连续序列

    • 任何提到“连续整数”或“序列”的问题,都应该想到 集合 + 邻居

    • 示例:Longest Consecutive Sequence (LC 128):

      • 将所有数字插入到集合中
      • 对于每个数字,只有在num - 1不在集合中时才扩展(即,它是序列的开始)。