Rabin-Karp — rolling hash, O(n+m) expected
WHAT problem are we solving?
Given a text of length and a pattern of length , find every position where occurs in (i.e. ).
The naive approach checks each of the windows by comparing characters → worst case. Rabin-Karp aims for expected.
WHY hashing helps
If , the strings are definitely different — skip instantly. If , they are probably equal, so we verify. Equal strings always have equal hashes, so we never miss a match. The only risk is a false positive (collision), which costs an extra check.
HOW: building the hash from first principles
Treat a string as a number in base (think of digits). For a string of length with character codes :
Deriving the rolling update
We have the hash of window :
We want for window . Three operations:
- Remove the leading char , which contributes .
- Shift left (multiply by ): every remaining term's exponent goes up by 1.
- Add the new trailing char .
So:
Why this step? Subtracting kills the old high-order digit; multiplying by slides everyone over; adding inserts the new low-order digit. All — that's the whole speedup.

Complexity — WHY expected
- Precompute and : .
- Slide across windows, each update : .
- Verify only on hash matches. With a good prime , the chance of a spurious match is about , so expected verification cost is tiny → total expected.
- Worst case (every window collides, e.g. adversarial input with small ).
Worked Example 1 — tiny by hand
Search in . Let base , , code .
- .
- Window 0 = "aa": . Why? digits are . → skip.
- Roll to window 1 = "ab": . . Why? removed leading 'a'(=0), shifted, added 'b'(=1). Matches → verify → "ab"=="ab" ✓. Match at index 1.
Worked Example 2 — a collision (steel-man)
, with chosen so two different strings hash equal. Suppose by bad luck.
- Hashes match → we must verify char-by-char.
- Verification fails → we correctly reject. Why this matters: the hash is a filter, not a proof. Skipping verification would report a fake match.
Common Mistakes
Flashcards
Rabin-Karp core idea
Why verify after a hash match?
Rolling update formula
Why multiply by in the roll?
Expected vs worst time
Role of the prime
What must be precomputed for rolls?
How to avoid negative hash values?
((x) % q + q) % q.Recall Feynman: explain to a 12-year-old
Imagine every word is turned into a secret number using its letters, like a fingerprint. To find a word hidden inside a long sentence, you slide a window and compute its fingerprint. Computing a brand-new fingerprint each time is slow — but here's the magic: when you slide one letter over, you just erase the first letter's part and add the new letter's part, super fast. If two fingerprints match, you double-check the actual letters (because rarely two different words share a fingerprint). That double-check is your safety net.
Connections
- Hashing — polynomial / modular hash foundations
- Modular Arithmetic — why we use a prime and avoid negatives
- Knuth-Morris-Pratt — guaranteed (no collisions) via failure function
- Z-Algorithm — another linear pattern matcher
- String Hashing for Substring Comparison — same rolling idea for range equality
- Birthday Paradox — intuition for collision probability
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, Rabin-Karp ka core idea simple hai: har string ko ek number (hash) mein convert kar do, aur fir do strings compare karne ke bajaye sirf unke numbers compare karo — ye mein ho jata hai. Hum text ke har length- window ka hash nikalte hain aur pattern ke hash se compare karte hain. Agar match nahi hua to seedha skip, agar match hua to character-by-character verify karte hain (kyunki kabhi-kabhi alag strings ka bhi same hash aa sakta hai — usko collision kehte hain).
Sabse important magic hai rolling hash. Har window ka hash dobara se scratch se nikalna slow hoga ( har baar). Lekin jab window ek step aage slide karta hai, to hum bas teen kaam karte hain: purane pehle character ka contribution hatao (), baaki sab ko shift karo (), aur naya last character add karo. Iss "Drop, Slide, Add" se update sirf mein ho jata hai — yahi puri speed ka raaz hai.
Ek galti jo sab karte hain: hash match ho gaya to maan lete hain string match ho gayi. Galat! Hash sirf ek filter hai, proof nahi. Hamesha verify karo. Dusri common galti — subtraction ke baad negative value aa jati hai modular arithmetic mein, to ((x % q) + q) % q likho taaki value positive rahe. Aur hamesha bada prime lo (jaise ), warna collisions badh jayenge aur time ban jayega.
Overall, agar prime accha ho to expected time aata hai, jo naive se bahut fast hai. Competitive programming mein ye technique substring comparison ke liye bhi kaam aati hai, isliye iska intuition pakka karna zaroori hai.