3.8.1String Algorithms

Naive pattern matching — O(nm)

1,822 words8 min readdifficulty · medium

WHAT is the problem?

  • TT = "ABABCABABA", PP = "ABA". We want every place "ABA" sits inside TT.
  • A shift ss is valid if all mm characters line up.

WHY does the naive method work at all?


HOW does it run? (derive the pseudocode from scratch)

We build it step by step from the definition.

  1. We must consider every shift ss from 00 to nmn-m. → outer loop.
  2. For a fixed ss, "is this shift valid?" means: compare P[0]P[0] with T[s]T[s], P[1]P[1] with T[s+1]T[s+1], … → inner loop over j=0m1j = 0 \ldots m-1.
  3. The moment any character mismatches, this shift is dead — break early (optimization), no point checking the rest.
  4. If the inner loop finishes without breaking, all mm chars matched → record ss.
NAIVE-MATCH(T, P):
    n = len(T);  m = len(P)
    for s = 0 to n - m:           # candidate start positions
        j = 0
        while j < m and T[s+j] == P[j]:
            j = j + 1
        if j == m:                # inner loop ran to completion
            report match at s

WHY is it O(nm)? (derive the bound)

Figure — Naive pattern matching — O(nm)


Recall Feynman: explain to a 12-year-old

Imagine you have a long sentence and a short word written on a transparent ruler. You lay the ruler at the very start of the sentence and check letter by letter: does the first letter match? second? If all letters of the little word match the letters underneath, you found it! If at any point a letter is wrong, you stop, slide the ruler one step to the right, and try again from the beginning of the word. You keep sliding until the ruler reaches the end of the sentence. That sliding-and-checking is the whole trick. It's simple but can be slow because every time you slide, you start checking from scratch.


Active Recall

How many candidate starting positions does naive matching check for text length n and pattern length m?
nm+1n - m + 1 (positions 00 through nmn-m); beyond that the pattern overruns the text.
What is the worst-case time complexity of naive pattern matching?
O(nm)O(nm) — more precisely Θ((nm+1)m)\Theta((n-m+1)m).
Give a worst-case input for naive matching.
Text all same char like "AAAA…A" with pattern "AAA…AB" — every shift matches m1m-1 chars then fails on the last.
Why can naive matching behave like O(n) in practice?
On typical/random text, mismatches occur in the first 1–2 characters, so the inner loop rarely runs near mm times.
What single idea distinguishes naive matching from KMP?
Naive forgets all comparison info and restarts j=0j=0 each shift; KMP reuses already-matched info to skip redundant comparisons.
What is the role of the early break in the inner loop?
Stop comparing as soon as one character mismatches — saves work without changing the result.
What defines a "valid shift" s?
A shift where T[s..s+m1]=P[0..m1]T[s..s+m-1] = P[0..m-1], i.e. all mm characters line up.

Connections

  • KMP Algorithm — removes redundant rechecks using a prefix function → O(n+m)O(n+m).
  • Boyer-Moore Algorithm — skips ahead using bad-character/good-suffix rules.
  • Rabin-Karp Algorithm — hashes windows to compare in O(1)O(1) expected.
  • Big-O Notation — basis for the O(nm)O(nm) analysis.
  • Sliding Window Technique — the "slide the pattern" view generalizes here.
  • Substring Search Problem — the parent problem this solves.

Concept Map

find all

only from 0 to n-m

try every one

correct by

outer loop

inner loop

mismatch

all m match

runs n-m+1 times

up to m per shift

worst case

Pattern matching problem

Valid shifts s

n-m+1 candidates

Naive brute force

Correct by exhaustion

Slide pattern each s

Compare char by char

Break early

Report match at s

Time O nm

Theta nm on AAA...A

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Naive pattern matching ka idea bilkul simple hai: tumhare paas ek bada text TT hai (length nn) aur ek chhota pattern PP hai (length mm), aur tumhe dhoondhna hai ki PP text ke andar kahan-kahan aata hai. Tareeka? Pattern ko text ke upar slide karo — pehle position 0 par rakho, fir 1, fir 2... har position par letter-by-letter check karo ki match ho raha hai ya nahi. Agar saare mm characters match ho gaye to wahan ek match mil gaya; agar beech mein koi ek bhi mismatch hua to turant ruk jao (early break) aur agle position par slide kar do.

Kitni positions check karni padti hain? Sirf 00 se nmn-m tak, yaani nm+1n-m+1 positions — kyunki uske aage pattern text se bahar nikal jaayega. Har position par worst case mein mm comparisons lagte hain, isliye total time O(nm)O(nm) ho jaata hai. Yeh worst case tab aata hai jab text mein bahut repetition ho, jaise T=T="AAAAA" aur P=P="AAB" — har baar last character par jaake fail hota hai, full kaam karna padta hai.

Practical baat: real English text ya random data par yeh actually kaafi fast chalta hai, kyunki zyadatar jagah pehle ya doosre character par hi mismatch ho jaata hai, to inner loop chhota reh jaata hai — almost O(n)O(n) behave karta hai. Lekin guarantee nahi de sakte, isliye worst case ke liye KMP, Boyer-Moore ya Rabin-Karp jaise smart algorithms aaye, jo pehle se match kiya hua information reuse karke redundant comparisons skip karte hain. Naive ki sabse badi "kamzori" yahi hai ki har slide par wo sab kuch bhool kar j=0j=0 se phir shuru karta hai.

Go deeper — visual, from zero

Test yourself — String Algorithms

Connections