目录
- 1. 问题重述
- 2. 问题求解
- 2.1 暴力法
- 2.2 哈希表法
- 2.3 集合法
- 3. 总结
1. 问题重述
给定两个列表 A A A 和 B B B,它们的长度分别为 n n n 和 m m m。我们要检查的是,是否存在 x ∈ A x\in A x∈A,使得 x ∈ B x\in B x∈B。
以下介绍若干种方法并记录下相应的耗时。
测试数据为:
A = list(range(1, 10**7 + 1))
B = list(reversed(range(10**7, 2 * 10**7)))
2. 问题求解
2.1 暴力法
遍历 A A A,然后判断 A A A 中的每个元素是否出现在了 B B B 中。
def check(A, B):for num in A:if num in B:return Truereturn False
时间复杂度为 O ( n m ) O(nm) O(nm)。预估耗时 480000 480000 480000 秒。
2.2 哈希表法
考虑到哈希表的查找是 O ( 1 ) O(1) O(1) 的,我们可以将 B B B 变为哈希表。
def check(A, B):B = set(B)for num in A:if num in B:return Truereturn False
构建哈希表需要 O ( m ) O(m) O(m) 的时间,所以总时间复杂度为 O ( n + m ) O(n+m) O(n+m)。实际耗时约为 0.51 ∼ 0.53 0.51\sim0.53 0.51∼0.53 秒。
鉴于构造的数据具有对称性,即使一开始选择对 A A A 构造哈希表,最终的耗时也几乎一致。
2.3 集合法
原问题等价于: ∃ x ∈ set ( A ) , s.t. x ∈ set ( B ) \exists \,x\in \text{set}(A),\; \text{s.t.}\, x\in\text{set}(B) ∃x∈set(A),s.t.x∈set(B),即 set ( A ) ∩ set ( B ) ≠ ∅ \text{set}(A)\cap \text{set}(B)\neq \varnothing set(A)∩set(B)=∅。
def check(A, B):A = set(A)B = set(B)return bool(A.intersection(B))
计算交集需要 O ( min ( n , m ) ) O(\min(n,m)) O(min(n,m)) 的时间,总时间复杂度同样为 O ( n + m ) O(n+m) O(n+m)。实际耗时约为 0.5 0.5 0.5 秒左右,比上一种方法略快。
3. 总结
下表总结了各个方法的速度比较:
方法 | 耗时(秒) |
---|---|
暴力法 | ≈ 480000 \approx480000 ≈480000 |
哈希表法 | 0.51 ∼ 0.53 0.51\sim0.53 0.51∼0.53 |
集合法 | 0.5 0.5 0.5 |
如果有更快的方法欢迎在评论区补充~