Longest Happy Prefix

hard strings kmp prefix function

Problem

A happy prefix is a non-empty prefix of a string that is also a suffix (but not the whole string itself). Given a string s of lowercase letters, return the longest happy prefix of s, or "" if none exists.

Inputs = "level"
Output"l"
The proper prefixes are "l", "le", "lev", "leve"; the only one that is also a suffix is "l".
Inputs = "ababab"
Output"abab"
"abab" is both a prefix and a suffix; the prefix and suffix may overlap.

def longest_prefix(s):
    n = len(s)
    lps = [0] * n          # lps[i] = longest prefix==suffix of s[:i+1]
    length = 0             # length of current matching prefix
    i = 1
    while i < n:
        if s[i] == s[length]:
            length += 1
            lps[i] = length
            i += 1
        elif length > 0:
            length = lps[length - 1]   # fall back
        else:
            lps[i] = 0
            i += 1
    return s[:lps[n - 1]]   # answer is a prefix of that length
function longestPrefix(s) {
  const n = s.length;
  const lps = new Array(n).fill(0); // lps[i] = longest prefix==suffix
  let length = 0;                   // length of current matching prefix
  let i = 1;
  while (i < n) {
    if (s[i] === s[length]) {
      length++;
      lps[i] = length;
      i++;
    } else if (length > 0) {
      length = lps[length - 1];     // fall back
    } else {
      lps[i] = 0;
      i++;
    }
  }
  return s.slice(0, lps[n - 1]);    // answer is a prefix of that length
}
String longestPrefix(String s) {
    int n = s.length();
    int[] lps = new int[n];         // lps[i] = longest prefix==suffix
    int length = 0;                 // length of current matching prefix
    int i = 1;
    while (i < n) {
        if (s.charAt(i) == s.charAt(length)) {
            length++;
            lps[i] = length;
            i++;
        } else if (length > 0) {
            length = lps[length - 1];   // fall back
        } else {
            lps[i] = 0;
            i++;
        }
    }
    return s.substring(0, lps[n - 1]);  // prefix of that length
}
string longestPrefix(string s) {
    int n = s.size();
    vector<int> lps(n, 0);          // lps[i] = longest prefix==suffix
    int length = 0;                 // length of current matching prefix
    int i = 1;
    while (i < n) {
        if (s[i] == s[length]) {
            length++;
            lps[i] = length;
            i++;
        } else if (length > 0) {
            length = lps[length - 1];   // fall back
        } else {
            lps[i] = 0;
            i++;
        }
    }
    return s.substr(0, lps[n - 1]);     // prefix of that length
}
Time: O(n) Space: O(n)