算法 Day1-数组 / 哈希 + 双指针

"需要快速判断某个值是否出现过?" → 哈希。

"两个位置一起移动、避免重复枚举?" → 双指针。

"数组里找两数关系、去重、原地操作?" → 优先想 HashMap / Set / 双指针。

Part A|数组 + HashMap / Set

1. 数组到底是什么?

数组本质上是一段连续存储的同类型/同一逻辑集合数据。

python 复制代码
nums = [1, 2, 3, 4]
python 复制代码
按下标访问:O(1)
尾部 append:均摊 O(1)
中间插入:O(n)
中间删除:O(n)
查找某个值:O(n)

严格来说 Python list 不是传统意义上的固定长度数组,它更接近动态数组,但在 LeetCode 和机考中,我们直接把它当数组使用。

2.HashMap / Set 是什么?

python 复制代码
d = {}
s = set()
dict → key : value
set  → 只有 key

Hash 查找是平均 O(1),不是绝对 O(1)。

理论最坏情况下,由于哈希冲突等原因,性能可能退化。

什么时候应该想到哈希?

python 复制代码
是否出现过
重复
频率
计数
两数之和
映射关系
第一次出现位置
字符统计
O(n) 内查找

尤其是:

"数组里找两个数满足某种关系。"

因为 Set 中不能存在重复元素。

所以 Set 最典型的用途就是:

去重 + 快速判断某个元素是否存在。

什么是 Hash Table?为什么查询快?

哈希表是一种通过哈希函数将 Key 映射到存储位置的数据结构,底层通常基于桶数组实现。

在查询一个 Key 时,首先计算 Key 的 hash 值,再根据 hash 值定位到对应的 bucket,而不需要像线性表一样从头遍历,因此在哈希分布比较均匀的情况下,查找、插入和删除的平均时间复杂度可以达到 O(1)。

但是不同 Key 可能映射到同一个位置,这叫哈希冲突。常见解决方式包括链地址法和开放寻址法。因此哈希表的 O(1) 一般指平均时间复杂度,极端冲突情况下性能可能退化。

为什么 HashSet 查询是 O(1)?

因为 HashSet 通常基于哈希表实现。查询元素时不是遍历 Set 中所有元素,而是先计算元素的 hash 值,通过 hash 值直接定位到对应的 bucket,再进行必要的比较,所以平均时间复杂度是 O(1)。

哈希表本质上干的事情,就是把"按内容查找"转换成了"算出位置后按位置查找"。

python 复制代码
List 查找:

May 在哪?
↓
A → B → C → D → May
          O(n)


HashSet 查找:

May 在哪?
↓
hash("May")
↓
bucket 7
↓
直接去 bucket 7
          平均 O(1)

Part B|双指针

  1. 双指针到底是什么?

双指针严格来说不是数据结构,而是一种遍历技巧。

核心思想:

不让两个位置彼此独立地枚举,而是根据题目性质,让两个指针有规律地移动。

常见两类。

左右指针

python 复制代码
L →           ← R
python 复制代码
有序数组
回文
两数之和
盛水

快慢指针

python 复制代码
slow →
fast ----->

例如:

python 复制代码
原地删除
移动零
链表环
去重

什么时候应该想到双指针?

python 复制代码
有序数组
两个数满足某关系
原地修改
删除元素
去重
移动元素
首尾比较
回文
区间收缩

"要求 O(1) 额外空间,并原地修改数组"

尤其要想到:快慢指针

哈希练习:LeetCode 1. 两数之和

双指针练习:LeetCode 167. 两数之和 II

练习题

练习 1|LeetCode 217. 存在重复元素

练习 2|LeetCode 283. 移动零 快慢指针

核心思想:用一个指针 i记录"下一个非零元素应该放的位置",遍历数组把非零元素往前挪,最后把剩余位置补 0。

练习 3|LeetCode 49. 字母异位词分组 hint:同一组字符串拥有相同的 key

练习 4|LeetCode 15. 三数之和

机考视角

通常包装

python 复制代码
订单ID是否重复
用户编号配对
设备记录去重
字符串统计
按照某规则找到两个元素
区间两端不断收缩

常见优化路线:

python 复制代码
双循环 O(n²)
↓
HashMap / Set
↓
O(n)
python 复制代码
数组排序
↓
左右双指针
python 复制代码
是否有优化空间?
是否可以利用有序性 → 双指针

面试手撕训练|今天选:三数之和

最直接的方法是三重循环枚举三个元素,时间复杂度 O(n³),数据量大时不可接受。

我可以先对数组排序,然后固定第一个数字,把剩下的问题转换为有序数组的两数之和。对于剩余区间使用左右双指针,如果三数之和小于 0,则左指针右移;如果大于 0,则右指针左移。这样每固定一个元素,剩余部分只需要 O(n) 扫描,因此整体时间复杂度降低为 O(n²)。

这道题还需要重点处理重复答案,所以固定元素以及找到答案后,都需要跳过相同值。

Cheat Sheet|Day 1

HashMap / Set

python 复制代码
看到这些想到哈希
出现过没有
重复
计数
频率
映射关系
两数之和
快速查找

Python

sql 复制代码
seen = set()

if x in seen:
    ...

seen.add(x)

Dict:

d = {}

d[key] = value

if key in d:
    ...

复杂度通常:

python 复制代码
查询:平均 O(1)
插入:平均 O(1)
删除:平均 O(1)

空间:

python 复制代码
O(n)

双指针

python 复制代码
左右指针识别信号
有序数组
首尾比较
两数关系
回文
区间收缩

模板:

python 复制代码
left = 0
right = len(nums) - 1

while left < right:
    if ...:
        left += 1
    else:
        right -= 1

快慢指针识别信号

python 复制代码
原地修改
删除
去重
移动元素

模板:

python 复制代码
slow = 0

for fast in range(len(nums)):
    if condition:
        nums[slow] = nums[fast]
        slow += 1

两个判断:

需要把"查找"从 O(n) 降下来 → 考虑 Hash。
两个变量存在单调关系,不需要所有组合都枚举 → 考虑双指针。

相关推荐
广州山泉婚姻7 小时前
Python序列号源码分析
python
计算机源码社7 小时前
【大数据项目实战】基于大数据的影视内容生态综合质量分析与可视化-基于数据挖掘的影视内容类型共现与口碑聚类分析系统
大数据·人工智能·python·数据挖掘·数据分析·毕业设计·课程设计
C^h7 小时前
pytorch 适合初学者 0基础学习
人工智能·pytorch·python
小柯南敲键盘8 小时前
跨马翻译:AI批量图片翻译工具,跨境电商视频字幕翻译与智能抠图一体搞定
人工智能·python·音视频
2601_962297258 小时前
Python里behave和pytest-bdd哪个更适合中大型项目?为什么?
python·bdd·行为驱动开发·behave·pytest-bdd
2601_967760788 小时前
2026年PDF压缩与页码添加工具技术实测:性能、算法与本地化适配深度对比
算法·pdf
不会就选b9 小时前
算法日常・每日刷题--<贪心>7
数据结构·算法·leetcode
moonrailgun9 小时前
用 Node.js 复刻 Codex Astra 的终端星光
前端·javascript·算法
罗西的思考10 小时前
[Agent Memory / 强化学习] MemPO源码学习笔记 ---(1)--- 总体
人工智能·算法·机器学习