ADVANCED TECHNIQUES / ALGORITHM BRIEF

Rolling hash

A rolling hash turns each substring of a fixed length into a number that can be updated in O(1) as the window slides one character: remove the leftmost character's contribution, multiply by the base, and add the new character.

AdvancedPhase 08 / Topic 4 of 7Mental modelComplexityEdge cases
01

Overview

A rolling hash turns each substring of a fixed length into a number that can be updated in O(1) as the window slides one character: remove the leftmost character's contribution, multiply by the base, and add the new character. Comparing numbers is much faster than comparing strings.

Rabin-Karp uses this to search for a pattern in O(n + m) on average: compare the window's hash with the pattern's hash, and verify characters only when the hashes match. With binary search on length, rolling hashes also find the longest repeated substring. Collisions are possible, so use a large modulus, double hashing, or verification.

A fingerprint for each window

Instead of comparing two long sentences word by word, compare their fingerprints. Sliding a window one character updates the fingerprint instantly, like adjusting a running total. Only when two fingerprints match do you check the actual words.

02

When to use it

  • Compare many substrings of the same length quickly.
  • Find duplicate or repeated substrings (DNA sequences, longest duplicate).
  • Pattern search when multiple patterns share a length.
  • Combine with binary search on the answer length.
03

Problem patterns it solves

Rabin-Karp search

Recognize it when: find a pattern with hashing.

  • 28. Find the Index of the First Occurrence in a String
  • 686. Repeated String Match
Duplicate fixed-length substrings

Recognize it when: all substrings of length k that occur more than once.

  • 187. Repeated DNA Sequences
  • 1316. Distinct Echo Substrings
Binary search + hashing

Recognize it when: longest substring that repeats or is common.

  • 1044. Longest Duplicate Substring
  • 718. Maximum Length of Repeated Subarray
  • 1923. Longest Common Subpath
Palindrome checks by hash

Recognize it when: compare forward and reverse hashes of a substring.

  • 214. Shortest Palindrome (hash variant)
  • 1960. Maximum Product of the Length of Two Palindromic Substrings
Modular number building

Recognize it when: remainder of a huge number built digit by digit, as in your repo's modular trick.

  • 1015. Smallest Integer Divisible by K
  • 1018. Binary Prefix Divisible By 5
04

Where it is used in real software

rsync and deduplication

rsync uses a rolling checksum to find matching blocks between files; backup systems use content-defined chunking with rolling hashes to deduplicate data.

Plagiarism detection

Tools like MOSS fingerprint documents by hashing overlapping k-grams.

Malware scanning

Antivirus engines compare rolling hashes of file windows against known signature hashes.

05

Key terms

Polynomial hash
hash(s) = s[0] x B^(k-1) + s[1] x B^(k-2) + ... + s[k-1], mod M.
Base B
A number larger than the alphabet size, often 31, 131, or 256.
Modulus M
A large prime such as 1e9 + 7 keeps values bounded.
Collision
Different strings with the same hash; verify or use two hashes.
Prefix hash
h[i] = hash of s[0..i); any substring hash is derived in O(1).
06

How it works, step by step

  1. 1
    Hash the pattern and the first window

    h = (h x B + code) mod M for each character.

  2. 2
    Precompute B^(k-1) mod M

    The weight of the leftmost character in a window of length k.

  3. 3
    Slide

    h = (h - left x B^(k-1)) x B + right, all mod M, keeping h non-negative.

  4. 4
    Compare

    If the hashes match, verify the characters to rule out a collision.

  5. 5
    For substring queries

    hash(l, r) = h[r] - h[l] x B^(r - l), mod M.

07

Rolling a length-3 window over "abcd"

a = 1, b = 2, c = 3, d = 4, base B = 10 (no modulus, for readability)

Step 1 / 2
WindowComputationHash
abc1 x 100 + 2 x 10 + 3123
bcd(123 - 1 x 100) x 10 + 4234

NOWWindow: abc | Computation: 1 x 100 + 2 x 10 + 3 | Hash: 123

The second hash came from the first in O(1) instead of rehashing three characters. With base 10 the hash is literally the digits; real implementations use a larger base and a modulus.

08

Implementation

// Rabin-Karp with verification; BigInt-free by keeping values below 2^53function rabinKarp(text, pattern) {  const n = text.length, m = pattern.length;  if (m === 0) return 0;  if (m > n) return -1;  const B = 131, M = 1_000_000_007;  let high = 1; // B^(m-1) mod M  for (let i = 1; i < m; i++) high = (high * B) % M;   let hp = 0, ht = 0;  for (let i = 0; i < m; i++) {    hp = (hp * B + pattern.charCodeAt(i)) % M;    ht = (ht * B + text.charCodeAt(i)) % M;  }  for (let i = 0; ; i++) {    if (hp === ht && text.startsWith(pattern, i)) return i; // verify on hash match    if (i + m >= n) return -1;    ht = (ht - (text.charCodeAt(i) * high) % M + M) % M; // remove left char    ht = (ht * B + text.charCodeAt(i + m)) % M;          // add right char  }} // 187. Repeated DNA Sequences: 2 bits per base, 20-bit window, exact (no collisions)function findRepeatedDnaSequences(s) {  const code = { A: 0, C: 1, G: 2, T: 3 };  const seen = new Set(), added = new Set(), result = [];  let hash = 0;  for (let i = 0; i < s.length; i++) {    hash = ((hash << 2) | code[s[i]]) & 0xfffff; // keep the last 10 bases    if (i < 9) continue;    if (seen.has(hash) && !added.has(hash)) {      added.add(hash);      result.push(s.slice(i - 9, i + 1));    }    seen.add(hash);  }  return result;}
09

Complexity and performance

Slide one stepO(1)

Remove, multiply, add.

Rabin-Karp averageO(n + m)

Worst case O(n x m) with many collisions.

Binary search + hashO(n log n)

Longest duplicate substring.

Prefix hashesO(n) build, O(1) query

Any substring hash.

10

Trade-offs

Speed vs certainty

Hash comparisons are fast but can collide. Verify matches, or use two independent hashes to make collisions astronomically unlikely.

Overflow handling

In JavaScript, keep intermediate products below 2^53 (base x modulus must fit), or use BigInt. In Java, use long with a modulus around 1e9, or careful 64-bit arithmetic.

11

Variants and related techniques

Double hashing

Two moduli (or bases) together reduce collision probability to about 1 / (M1 x M2).

2D rolling hash

Hash rows then columns to find a submatrix pattern.

Bit-packed exact hashing

For tiny alphabets (DNA), pack characters into bits for collision-free hashes.

12

Common mistakes

  • Negative values after subtraction.

    Fix: Add M before taking the modulus: (h - x + M) % M.

  • Overflow in JavaScript multiplication.

    Fix: 131 x (1e9 + 7) is safe, but (1e9) x (1e9) is not; keep one operand small or use BigInt.

  • Trusting a hash match without verification.

    Fix: Compare characters on equal hashes, or use double hashing.

13

Interview questions

How does the rolling update work?

Subtract the contribution of the outgoing character (its code times B^(k-1)), multiply the remainder by B to shift every character one position left, then add the incoming character.

How do you deal with hash collisions?

Verify the actual characters when hashes match, use a large prime modulus, or maintain two different hashes and require both to match.

14

Practice problems

ProblemDifficultyWhat it trains
187. Repeated DNA SequencesMediumBit-packed rolling window.
1015. Smallest Integer Divisible by KMediumRolling remainder.
28. Find the Index of the First OccurrenceEasyRabin-Karp.
718. Maximum Length of Repeated SubarrayMediumBinary search + hash.
1044. Longest Duplicate SubstringHardBinary search + hash + verification.