COMP5270 Week 6 总结:Hashing and Friends(题解 + 知识点)
课程: COMP5270 - Randomness, Probability, and Algorithms
学期: S1 2026
来源: Week 6 - Hashing and Friends, Week 6 - Going further, Week 6 - Tutorial 6 (Solutions)
Part 1: Tutorial 6 详细题解
Warm-up
Problem 1: Hash table 和 Bloom filter 的区别
题目: 从时间、空间复杂度和 guarantee 角度总结 hash table 与 Bloom filter 的关键区别。
题解:
二者都用 hashing,但目标不同。
Hash table
Hash table 是 dictionary data structure,用来维护集合
Insert(x);Lookup(x);Remove(x).
它真的存储元素本身,因此只要 collision handling 正确,查询结果不会错。随机性主要影响运行时间。
典型 separate chaining 的空间约为:
其中:
是 universe size; 是 bucket 数; 是已存元素数。
若
是常数,则 Insert/Lookup/Remove 期望时间都是:
但 worst-case 仍可能是
Bloom filter
Bloom filter 不存储元素本身,只维护一个 bit array
插入
置为 1。查询
它的空间:
如果
Bloom filter 的 guarantee:
- 无 false negative:插入过的元素一定返回 yes;
- 可能有 false positive:没插入过的元素也可能返回 yes;
- 经典 simple version 不支持直接删除。
时间上,Insert 和 Lookup 都是
worst-case:
若
本题用到的知识点:
- Hash table 存元素,Bloom filter 只存 membership bits。
- Bloom filter 牺牲正确性换空间,只会 false positive。
- Hash table 的随机性主要控制 expected time,Bloom filter 的随机性控制 error rate。
Problem 2:
Separate chaining 的期望时间
题目: 证明 separate chaining 中 Insert,
Lookup, Remove 的 expected time 都是
题解:
Separate chaining 中,每个 bucket 维护一个 list。操作
里已有多少元素。
假设在操作
表示与
若 hash family 是 universal,则对任意
用期望线性性:
每次操作还有常数级基本成本,所以:
Worst-case 中,所有元素都可能落入同一个
bucket,此时单次操作要扫描长度
本题用到的知识点:
- Universal hashing 控制 pairwise collision probability。
- 指示变量 + 期望线性性。
- Separate chaining 的成本等于 bucket load。
Problem Solving
Problem 3: Universal hash family 中不一定取等号
题目: 给一个 universal hash family
不是等号。
题解:
令:
定义两个 hash functions:
令:
对唯一一对不同输入
所以:
但:
于是:
这说明 universal hashing 的定义只要求 collision probability 不超过
本题用到的知识点:
- Universal hash family 是 inequality guarantee。
- Universal 比 strongly universal 弱。
- Collision probability 可以严格小于
。
Problem 4:
三数组 的 expected algorithm
题目: 给三个长度为
要求 expected
题解:
a) 朴素算法
枚举所有 triples:
for i in 1..n: |
共有
b) Hash table 算法
先把
然后枚举所有
是否在
算法:
T = empty hash table |
c) 正确性
如果存在
那么
反过来,如果算法返回 true,则存在某个 pair
因此返回 true 是正确的。
d) 时间复杂度
插入
枚举
Worst-case 取决于 collision handling:
- chaining / linear probing:单次操作 worst-case
,总 worst-case 可到 ; - cuckoo hashing:lookup worst-case
,但 insertion worst-case 仍可能大。
本题用到的知识点:
- 用 hash table 把三重枚举降到二重枚举。
- Expected
hash operation。 - Correctness 分 yes case 和 no case。
- Expected time 与 worst-case time 的区别。
Problem 5: Perfect hashing 两层结构
题目: 两层 hashing:第一层像 separate chaining,把
题解:
设第一层第
a) Secondary table 应该多大?
若第
为了让有 collision 的概率最多
令:
则:
b) Batch insertion
- 随机选择第一层 hash function
; - 把所有元素分到
个 bucket,得到 ; - 对每个 bucket
,开一个大小 的 secondary table; - 为该 bucket 随机选择 secondary hash function;
- 若发生 collision,则重新选择该 bucket 的 secondary hash function,直到无 collision。
因为每次成功概率至少
c) Lookup 期望时间
查询
- 第一层算
; - 第二层算
; - 直接查 secondary table 位置。
secondary table 被初始化为无 collision,所以 lookup 是 worst-case:
d) 总空间为什么是 ?
总空间主要是:
需要证明其期望是
展开:
所以:
当
当
若
因此 perfect hashing 总空间期望
本题用到的知识点:
- Two-level hashing / perfect hashing。
- 用 Markov 把 expected collisions 转成 collision-free 概率。
空间分析。 - Universal hashing 控制 pairwise collision。
Problem 6: Bloom filter 的 false positive rate
题目: Bloom filter 插入
题解:
令:
表示平均每个元素占多少 bit。
a) 某一位被置为 1 的概率
固定 array 中某个 bit
一次 hash 不打到它的概率是:
总共有
因此被置为 1 的概率:
用近似:
所以:
b) False positive probability
查询一个没有插入过的
在独立近似下:
c)
时最佳
要最小化:
标准结论是:
因此:
取整数:
一般情况下:
d)
的错误率
即约:
e) 固定 ,改变
错误率:
课程 solution 给出的近似结果:
| false positive rate | |
|---|---|
| 12 | 约 |
| 16 | 约 |
| 32 | 约 |
当
所以:
本题用到的知识点:
- Bloom filter false positive 来自多个 bit 被其他元素置 1。
- 近似
。 - 最优 hash 个数
。 - 固定
时错误率随 多项式下降。
Advanced
Problem 7: Bloom filter 如何支持 Remove?
题目: 扩展 Bloom filter,使其支持
Remove,并分析 guarantee。
题解:
普通 Bloom filter 不能直接删除,因为一个 bit 可能由多个元素共同置为
1。若删除
方法 1: Counting Bloom filter
把 bit array 改成 counter array。
Insert(x):对对应 counter 加 1; Remove(x):对应 counter 减 1;Lookup(x):所有对应 counter 都大于 0 才返回 yes。
优点:
- 支持删除;
- 若 counter 不 overflow,仍无 false negative。
代价:
- 空间从 bit 变成 small counters,增加常数因子;
- 仍可能 false positive。
方法 2: Deletion Bloom filter
额外维护一个 Bloom filter 记录被删除的元素。查询时:
- 原 filter 说 yes;
- deletion filter 没说 deleted;
- 才返回 yes。
这会引入新错误类型:deletion filter 可能 false positive,导致实际存在的元素被误判为 deleted,即产生 false negative。
所以 practical 上更常用 counting Bloom filter。
本题用到的知识点:
- 普通 Bloom filter 无法安全清零 bit。
- Counting Bloom filter 用 counter 支持删除。
- 删除结构可能引入 false negative。
- Bloom filter 的 guarantee 与数据结构变体相关。
Part 2: Week 6 讲义知识点
0. 基础版导读:hashing 解决的根本问题
Week 6 的主题是 Hashing and Friends。它解决的核心问题是:
universe 很大,但真正存储的 key 很少。怎样用接近 key 数量的空间,快速支持 insert、lookup、remove?
如果 universe 是 A[x]。这能做到
worst-case
Hashing 用一个函数:
把大 universe 压到小表里。
为什么 hash function 要随机选?
算法不是每次操作都重新随机。通常做法是:
- 初始化时从 hash family
中随机选一个 。 - 之后 insert/search/delete 都用同一个
。
这样做是为了避免固定 hash function 被坏输入针对。我们分析的是随机选择
两个重要概念:
- Universal hashing:任意两个不同 key collision
的概率最多
。 - Strongly universal hashing:任意两个不同 key 的 hash 值像独立均匀随机变量一样。
普通 universal hashing 已经足够证明 separate chaining 的 expected
separate chaining 为什么是
?
Separate chaining 是每个 bucket 放一个链表。设当前存了
查询 key
由 universal hashing:
所以和
加上访问本身,查询期望时间是
perfect hashing 的直觉
Perfect hashing 常用于 static dictionary:key 集合提前知道,之后主要查询。
目标是更强的 worst-case
- 第一层把所有 key 分到若干 bucket。
- 第
个 bucket 有 个 key。 - 给这个 bucket 单独建第二层表,大小约
。 - 随机挑第二层 hash function,直到这个 bucket 内无 collision。
为什么用
总空间不是
理解这个式子的方法是:
Bloom filter 是什么类型的错误?
Bloom filter 做 approximate membership query:
- 如果回答 not present,一定正确。
- 如果回答 present,可能是 false positive。
- 普通 Bloom filter 没有 false negative。
它用一个长度
对应位置设成 1。查询
false positive 的原因是:
如果插入
所以某一位是 1 的概率约为:
false positive rate 近似:
如果写成
为什么 Bloom filter 删除麻烦?
普通 Bloom filter 不能直接把某些 bit 从 1 改回 0。因为一个 bit
可能被多个元素共享。删除
Counting Bloom filter 把 bit 改成 counter:
- insert 时对应 counters 加 1。
- delete 时对应 counters 减 1。
- query 时检查 counters 是否都大于 0。
代价是空间更大,而且要考虑 counter overflow。
做题时怎么下手?
- 看到 expected chain length:定义 indicator,求 collision 期望。
- 看到 universal hashing:重点是任意 pair collision probability。
- 看到 perfect hashing:写
,把它解释成 pair 数。 - 看到 Bloom filter:先算某一 bit 为 0/1 的概率,再算
个位置全为 1。 - 看到 remove:普通 Bloom filter 不安全,优先考虑 counting Bloom filter。
1. Dictionary ADT 与 universe size
Dictionary 维护集合
Insert(x);Lookup(x);Remove(x).
设:
; ; - 通常
。
直接用大小为
2. 为什么需要随机 hash functions?
Pigeonhole principle 告诉我们,只要
解决思路:不是固定一个 hash function,而是从一个小而“足够随机”的
family
3. Strongly universal hashing
Strongly universal 要求对任意
它提供 pairwise independence。
多项式构造:在有限域
可得到 strongly universal family。
4. Universal hashing
Universal hashing 更弱,只要求碰撞概率:
Strongly universal 一定 universal,但反过来不一定。
常见构造:
其中
5. 分析 hash structures 时常用哪些随机性?
Universal hashing 通常足够做:
- expected bucket size;
- expected collision number;
- Markov / Chebyshev 类证明。
但 Chernoff / Hoeffding 通常需要 full independence,不能随便在 universal hashing 上直接使用。
6. Collision handling
Separate chaining
每个 bucket 存 linked list。空间:
期望操作时间:
Worst-case:
Open addressing
所有元素直接存在 array 中。若当前位置冲突,就按 probing sequence 找下一个位置。
常见方式:
- linear probing;
- quadratic probing;
- double hashing。
理想随机 permutation probing 下,unsuccessful lookup 期望时间:
Linear probing 可能因为 clustering 更差。
Cuckoo hashing
每个元素有两个可选位置。Lookup/Remove 检查两个位置即可:
Insert 可能触发 eviction chain,期望
7. Perfect hashing
Two-level hashing:
- 第一层 table 大小
; - 第
个 bucket 若有 个元素,第二层开 空间; - 重抽第二层 hash 直到无 collision。
保证:
- lookup worst-case
; - expected total space
。
核心公式:
8. Bloom filter
Bloom filter 使用:
- bit array
,长度 ; 个 hash functions。
操作:
- Insert: 将
个位置置为 1; - Lookup: 若
个位置全是 1 返回 yes,否则 no。
Guarantee:
- no false negative;
- false positive possible;
- simple version no remove。
空间:
时间:
False positive 近似:
其中
最优:
9. Going further: 为什么简单 hash functions 实践中有效?
Week 6 going-further 读物讨论 Mitzenmacher 和 Vadhan 的观点:理论 worst-case 分析下,2-universal 或低独立 hash family 的 guarantee 往往弱于 truly random hashing;但实践中简单 hash functions 表现常常接近 truly random。
解释思路是:真实数据并非 adversarial worst-case,可能本身含有 entropy。若数据流中每个新元素在给定过去元素后仍有足够 Renyi entropy,则 universal hashing + 数据自身随机性可以产生接近 ideal hashing 的效果。
应用包括:
- linear probing;
- chained hashing;
- balanced allocation;
- Bloom filters。
这个观点提醒:理论保证分 worst-case data 与 random-ish data,两者能得到的结论不同。
本周核心记忆
| 主题 | 关键结论 |
|---|---|
| Universal hashing | |
| Strongly universal | 两个不同输入输出 pairwise independent uniform |
| Chaining expected time | |
| Chaining worst-case | |
| Perfect hashing | |
| Bloom filter false positive | |
| Bloom optimal |
|
| Bloom guarantee | no false negative, possible false positive |
| Counting Bloom filter | 支持 remove,但空间变大 |