DrawCode Algorithm Visualizer • String • Medium

KMP Pattern Matching

Tags: String, Pattern Matching, LPS, Linear Time

1. One-Liner

Knuth–Morris–Pratt (KMP) finds every occurrence of a pattern in a text in O(n + m) by never re-checking text characters that already matched, using a longest proper prefix which is also suffix (LPS) table.


2. The Problem It Solves

Given text T of length n and pattern P of length m, find all starting indices where P occurs in T. Naive backtracking can take O(n·m) when the pattern has repeated prefixes; KMP avoids re-scanning T.


3. The Core Idea

When a mismatch happens after matching a prefix of P, you do not slide P by only one character blindly. The LPS tells you the longest prefix of P that is already aligned with the suffix of the matched portion, so you resume comparing from the next meaningful position in P.


4. How It Works (Table)

StepWhat Happens
1. Build LPSFor each index i in P, lps[i] = length of longest proper prefix of P[0..i] that is also a suffix of P[0..i].
2. Two pointersi scans T, j scans P.
3. MatchIf T[i] == P[j], advance both. If j == m, record a match and set j = lps[j-1].
4. MismatchIf j > 0, set j = lps[j-1] (no i move). If j == 0, increment i.

5. Dry Run Example

T = "ABABDABACD", P = "ABA". LPS for "ABA": [0,0,1]. Scan: match ABA at index 0; then shift using LPS. KMP avoids rechecking T from scratch after partial overlaps.


6. Key Properties

PropertyValue
TimeO(n + m)
SpaceO(m) for LPS
OnlineCan stream text with same machinery
DeterministicNo hashing; exact character comparison

7. Where It Is Used

DomainUse
BioinformaticsDNA motif scanning in long sequences
Editors / IDEsIncremental search, syntax highlighting engines
NetworkingPattern filters in packet inspection (alongside other algos)

8. Interview Tips

Derive why lps[j-1] on mismatch: longest border of the matched prefix. Contrast with Rabin–Karp (hashing) and Z-function (related self-similarity). Watch empty pattern and overlap outputs.


9. Comparison with Other Algorithms

AlgorithmTimeNotes
NaiveO(n·m) worstSimple, many rescan
KMPO(n + m)No hash; good for repetitive patterns
Rabin–KarpO(n + m) averageMultiple patterns with rolling hash
Boyer–MooreSublinear oftenSkips from end of pattern

10. Complexity

MetricValue
Preprocess (LPS)O(m) time, O(m) space
SearchO(n) time
TotalO(n + m) time, O(m) extra space

Implementation Example (PYTHON)

def kmp_search(text, pat):
    if not pat:
        return list(range(len(text) + 1))
    m = len(pat)
    lps = [0] * m
    length, i = 0, 1
    while i < m:
        if pat[i] == pat[length]:
            length += 1
            lps[i] = length
            i += 1
        elif length:
            length = lps[length - 1]
        else:
            lps[i] = 0
            i += 1
    out, j = [], 0
    for i in range(len(text)):
        while j and text[i] != pat[j]:
            j = lps[j - 1]
        if text[i] == pat[j]:
            j += 1
        if j == m:
            out.append(i - m + 1)
            j = lps[j - 1]
    return out

Interactive Visualizer Workspace

Explore step-by-step interactive animations, memory state tracking, and live multi-language execution in DrawCode.

Launch Interactive Visualizer