Skip to main content

Z-Algorithm

knoxiboy
EditReport

Z-Algorithm

The Z-Algorithm finds all occurrences of a pattern in a text in linear time O(N+M)O(N + M), where NN is the length of the text and MM is the length of the pattern.

Intuition

The algorithm constructs a Z-array where Z[i]Z[i] is the length of the longest substring starting from S[i]S[i] which is also a prefix of SS. To find a pattern PP in a text TT, we create a new string S = P + \text{"\"} + T.If. If Z[i]equalsthelengthofequals the length ofP$, we found a match!

Implementation

Python

def get_z_array(s):
n = len(s)
z = [0] * n
l, r, k = 0, 0, 0
for i in range(1, n):
if i > r:
l, r = i, i
while r < n and s[r - l] == s[r]:
r += 1
z[i] = r - l
r -= 1
else:
k = i - l
if z[k] < r - i + 1:
z[i] = z[k]
else:
l = i
while r < n and s[r - l] == s[r]:
r += 1
z[i] = r - l
r -= 1
return z

def z_algorithm(text, pattern):
# Note: The delimiter '$' is assumed to not appear in either text or pattern.
concat = pattern + "$" + text
l = len(concat)
z = get_z_array(concat)
res = []
# Start searching after pattern and delimiter to avoid redundant iterations
for i in range(len(pattern) + 1, l):
if z[i] == len(pattern):
res.append(i - len(pattern) - 1)
return res

Complexity Analysis

  • Time Complexity: O(N+M)O(N + M) where NN is text length and MM is pattern length.
  • Space Complexity: O(N+M)O(N + M) for the concatenated string and Z-array.
Telemetry Integration

Completed working through this block? Sync progress to workspace.