Python 3.11+
The code uses standard Python syntax and containers supported by the browser Judge. The Knuth-Morris-Pratt proof does not depend on a minor Python release.
Verify in Python docs(opens in a new tab)Use a prefix-function fallback table to match strings in linear time without rescanning text. Learn the algorithm's preconditions, state transition, correctness argument, Python cost model, and transfer from one focused drill to a full Interview Problem.
Recognize it when
Consider Knuth-Morris-Pratt when the prompt's constraints and required operations match this shape: Use a prefix-function fallback table to match strings in linear time without rescanning text.

Sign in to save your code and progress across devices. The lesson and problem statement remain public.
Knuth-Morris-Pratt (KMP) builds a prefix table where each position stores the longest proper pattern prefix that is also a suffix ending there. This records reusable partial-match structure.
The text index never moves backward. After a mismatch, already matched text remains useful because the prefix table identifies the next pattern alignment consistent with that suffix.
def prefix_trace(pattern):
prefix=[0]*len(pattern);trace=[]
for index in range(1,len(pattern)):
length=prefix[index-1];fallbacks=[]
while length and pattern[index]!=pattern[length]:fallbacks.append(length);length=prefix[length-1]
if pattern[index]==pattern[length]:length+=1
prefix[index]=length;trace.append([index,fallbacks,length])
return traceImplement prefix_trace(pattern). Return [index,fallbacks,prefix_length] for each index after the first.
Loading interactive editor.If it does not appear, the reference and starter code remain readable.Reload editor
While matched length is positive and the next symbols differ, replace length with the prefix value before it. If symbols then match, extend by one; do not discard the current text symbol prematurely.
def kmp_indexes(text,pattern):
if pattern=="":return list(range(len(text)+1))
prefix=[0]*len(pattern)
for index in range(1,len(pattern)):
length=prefix[index-1]
while length and pattern[index]!=pattern[length]:length=prefix[length-1]
if pattern[index]==pattern[length]:length+=1
prefix[index]=length
matches=[];length=0
for index,character in enumerate(text):
while length and character!=pattern[length]:length=prefix[length-1]
if character==pattern[length]:length+=1
if length==len(pattern):matches.append(index-len(pattern)+1);length=prefix[length-1]
return matchesImplement kmp_indexes(text,pattern). Return all start indexes including overlaps; empty pattern matches at every boundary.
Loading interactive editor.If it does not appear, the reference and starter code remain readable.Reload editor
After a full match, record its start and fall back using the final prefix value rather than resetting to zero. This permits overlapping occurrences such as aba inside ababa.
Say: “The prefix table tells how much of the pattern remains valid after mismatch. Text never retreats, and pattern fallback visits each prefix length a bounded number of times.” State empty-pattern and overlapping-match semantics and O(n + m) time.
Python 3.11+
The code uses standard Python syntax and containers supported by the browser Judge. The Knuth-Morris-Pratt proof does not depend on a minor Python release.
Verify in Python docs(opens in a new tab)Interview bounds depend on the stated representation, input model, and real Python operations.
| Operation | Average | Worst | Interview note |
|---|---|---|---|
| Knuth-Morris-Pratt complete workflow | O(m) | O(m) | Scan once while falling back through the already computed LPS chain on mismatch. |
O(m) for the focused Build a KMP Prefix Table implementation.
These are the mistakes most likely to survive a happy-path example and fail a boundary case.
Verify algorithm preconditions such as sorted input, nonnegative weights, acyclicity, or admissible heuristics before applying it.
Prevent it: State and verify this precondition before coding: The pattern, text, equality semantics, and reusable prefix or rolling-hash state are explicit.
Avoid
def kmp_prefix_table(pattern):
passUse instead
def kmp_prefix_table(pattern):
table = [0] * len(pattern)
length = 0
index = 1
while index < len(pattern):
if pattern[index] == pattern[length]:
length += 1
table[index] = length
index += 1
elif length > 0:
length = table[length - 1]
else:
index += 1
return tableWhere you will hit this: Build a KMP Prefix Table(opens in a new tab)
Resets to zero on mismatch and loses a shorter reusable border.
Prevent it: Preserve this proof obligation: Every skipped comparison is represented by an already verified prefix or a collision-checked hash candidate.
Avoid
def kmp_prefix_table(p):
out=[0]*len(p); length=0
for i in range(1,len(p)):
if p[i]==p[length]:length+=1;out[i]=length
else:length=0
return outUse instead
def kmp_prefix_table(pattern):
table = [0] * len(pattern)
length = 0
index = 1
while index < len(pattern):
if pattern[index] == pattern[length]:
length += 1
table[index] = length
index += 1
elif length > 0:
length = table[length - 1]
else:
index += 1
return tableWhere you will hit this: Build a KMP Prefix Table(opens in a new tab)
Include visited state, boundary cases, recursion depth, and hidden copying costs in correctness and complexity analysis.
Prevent it: Count every sort, slice, copy, membership check, heap update, and recursive frame before claiming O(m).
Avoid
def kmp_prefix_table(p):
out=[0]*len(p); length=0
for i in range(1,len(p)):
if p[i]==p[length]:length+=1;out[i]=length
else:length=0
return outUse instead
def kmp_prefix_table(pattern):
table = [0] * len(pattern)
length = 0
index = 1
while index < len(pattern):
if pattern[index] == pattern[length]:
length += 1
table[index] = length
index += 1
elif length > 0:
length = table[length - 1]
else:
index += 1
return tableWhere you will hit this: Lowest Common Ancestor in a BST(opens in a new tab)
Official Python documentation supports language behavior. Canonical problem pages provide additional practice context.
python-docs · checked 2026-07-27