algorithm
set theory
intersection
cardinality
approximation

Fast approximate algorithm for cardinality of sets intersection

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Computing the exact size of a set intersection can be expensive when the sets are huge, distributed, or streaming. In those cases, an approximate algorithm is often good enough, especially if you need a fast answer for similarity search, deduplication, telemetry, or large-scale analytics.

A Practical Strategy: Estimate Jaccard, Then Recover Intersection Size

One useful approach is to estimate the Jaccard similarity between two sets and then turn that estimate into an intersection estimate.

The Jaccard similarity is:

text
J(A, B) = |A ∩ B| / |A ∪ B|

If you also know or can estimate |A| and |B|, then you can estimate the intersection:

text
|A ∩ B| ≈ J(A, B) * (|A| + |B|) / (1 + J(A, B))

MinHash is a classic way to estimate Jaccard similarity efficiently.

Example MinHash Sketch

This small Python example builds a simple MinHash signature and uses it to estimate intersection size:

python
1import random
2
3def minhash_signature(values, seeds):
4    signature = []
5    for seed in seeds:
6        signature.append(min(hash((seed, value)) for value in values))
7    return signature
8
9def estimate_jaccard(sig_a, sig_b):
10    matches = sum(1 for a, b in zip(sig_a, sig_b) if a == b)
11    return matches / len(sig_a)
12
13def estimate_intersection(size_a, size_b, jaccard_estimate):
14    return jaccard_estimate * (size_a + size_b) / (1 + jaccard_estimate)
15
16set_a = set(range(0, 10000))
17set_b = set(range(5000, 15000))
18
19seeds = list(range(128))
20sig_a = minhash_signature(set_a, seeds)
21sig_b = minhash_signature(set_b, seeds)
22
23j = estimate_jaccard(sig_a, sig_b)
24i = estimate_intersection(len(set_a), len(set_b), j)
25
26print("estimated jaccard:", j)
27print("estimated intersection:", round(i))
28print("exact intersection:", len(set_a & set_b))

This technique is useful when you can afford a sketch per set but not an exact pairwise intersection scan for every comparison.

When HyperLogLog Helps

If the set sizes themselves are not known exactly, combine a Jaccard estimator such as MinHash with a distinct-count sketch such as HyperLogLog. HyperLogLog is strong at approximate cardinality estimation, but it does not directly give you intersection size by itself.

A common pattern is:

  • Use HyperLogLog for |A| and |B|
  • Use MinHash for Jaccard similarity
  • Derive |A ∩ B| from those estimates

That combination is often far more practical than exact set materialization in large systems.

Why Approximation Is Worth It

Approximate algorithms help when:

  • The sets are too large to intersect exactly in memory
  • The data arrives as streams
  • You need many repeated similarity checks
  • Network cost matters more than exactness

They trade a controlled amount of error for big gains in speed and memory efficiency.

Common Pitfalls

The biggest mistake is choosing an approximate algorithm without understanding what quantity it estimates. MinHash estimates Jaccard similarity, not intersection size directly. HyperLogLog estimates cardinality, not similarity.

Another issue is using sketches that are too small. Tiny signatures or low-register sketches save memory, but they increase error and variance. Approximation quality depends heavily on sketch size.

Developers also sometimes compare approximate and exact results on tiny datasets and conclude the method is useless because the estimate is not perfect. Approximate sketches are most valuable when exact computation is expensive enough that small error is acceptable.

Finally, remember that approximation errors can compound if you derive one estimate from another. If both the Jaccard estimate and the set-size estimates are noisy, the final intersection estimate inherits that uncertainty.

Summary

  • Fast approximate intersection size is often computed indirectly rather than by exact set overlap.
  • MinHash is a practical way to estimate Jaccard similarity.
  • If you know or estimate the set sizes, you can derive an approximate intersection cardinality.
  • HyperLogLog is useful for approximate set size, but not as a direct intersection estimator.
  • Approximate methods are most valuable when memory, latency, or scale makes exact computation too expensive.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.