A string is called a happy prefix if is a non-empty prefix which is also a suffix (excluding itself).
Given a string s
, return the longest happy prefix of s
. Return an empty string ""
if no such prefix exists.
Example 1:
Input: s = "level"
Output: "l"
Explanation: s contains 4 prefix excluding itself ("l", "le", "lev", "leve"), and suffix ("l", "el", "vel", "evel"). The largest prefix which is also suffix is given by "l".
Example 2:
Input: s = "ababab"
Output: "abab"
Explanation: "abab" is the largest prefix which is also suffix. They can overlap in the original string.
Constraints:
1 <= s.length <= 10^5
s
contains only lowercase English letters.class Solution:
def longestPrefix(self, s: str) -> str:
n = len(s)
for length in range(n - 1, 0, -1):
if s[:length] == s[n-length:]:
return s[:length]
return ""
The naive solution iterates through all possible prefix lengths from n-1
down to 1. For each length, it checks if the prefix of that length is equal to the suffix of the same length. If a match is found, it returns the prefix. If no match is found after checking all possible lengths, it returns an empty string.
The optimal solution uses the Knuth-Morris-Pratt (KMP) algorithm to compute the longest proper prefix which is also a suffix for each prefix of the string. This is done by constructing a "longest prefix suffix" (LPS) array. The last element of the LPS array gives the length of the longest happy prefix.
class Solution:
def longestPrefix(self, s: str) -> str:
n = len(s)
lps = [0] * n
length = 0
i = 1
while i < n:
if s[i] == s[length]:
length += 1
lps[i] = length
i += 1
else:
if length != 0:
length = lps[length - 1]
else:
lps[i] = 0
i += 1
return s[:lps[n - 1]]
n-1
times, and the string comparison s[:length] == s[n-length:]
takes O(length) time in the worst case. Since length
can be up to n-1
, the worst-case time complexity is O(n^2).n
, so the space complexity is O(n).