Skip to content
ΣDSA Patterns
Menu
Language

KMP / String Matching

Guide 2 of 6 · Path 2 of 6

Interactive

Mental model

A worked animation for this problem. Scrub steps or press space to pause; re-tell the invariant out loud.

Step 1 of 6
a
b
a
b
a
b

Happy prefix: nonempty proper prefix that equals a suffix. s = ababab.

Demo preview: These solutions pass the automated test suite but have not been human-reviewed. Treat trade-offs and prose as draft.

Longest Happy Prefix

Problem (restated)

A happy prefix is a non-empty proper prefix that is also a suffix. Return the longest happy prefix of s, or "".

Intuition

That is the definition of lps[n-1]. Build the LPS array of s and take s[:lps[n-1]].

Approaches

LPS of s

Unverified
Time O(n)Space O(n)

Idea. Standard LPS. Return the prefix of that length.

Walkthrough. level → l. ababab → abab. leetcode → "".

Trade-offs. Direct LPS read. Rolling hash can binary-search the length; more code.

Solution
export function longestPrefix(s: string): string {
  const n = s.length;
  if (n === 0) return "";
  const lps = new Array<number>(n).fill(0);
  let length = 0;
  for (let i = 1; i < n; i++) {
    while (length > 0 && s[i] !== s[length]) length = lps[length - 1]!;
    if (s[i] === s[length]) length++;
    lps[i] = length;
  }
  return s.slice(0, lps[n - 1]!);
}
export function longestPrefix(s: string): string {
  const n = s.length;
  if (n === 0) return "";
  const lps = new Array<number>(n).fill(0);
  let length = 0;
  for (let i = 1; i < n; i++) {
    while (length > 0 && s[i] !== s[length]) length = lps[length - 1]!;
    if (s[i] === s[length]) length++;
    lps[i] = length;
  }
  return s.slice(0, lps[n - 1]!);
}

Template connection

Longest happy prefix = LPS of the string. LC 459 uses the same last LPS value as a period.

Reflection