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 <= 105
s
contains only lowercase English letters.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to finding the longest happy prefix is like comparing every possible beginning of a word to its end. We check increasingly longer prefixes to see if they match the suffix of the same length.
Here's how the algorithm would work step-by-step:
def longest_happy_prefix_brute_force(input_string):
longest_happy_prefix = ""
for prefix_length in range(1, len(input_string)):
# Check prefixes of increasing length
prefix = input_string[:prefix_length]
suffix = input_string[len(input_string) - prefix_length:]
# Need to compare the prefix with the suffix to find matches
if prefix == suffix:
longest_happy_prefix = prefix
return longest_happy_prefix
The goal is to find the longest part of a word that also appears at the beginning. Instead of checking every possible part, we use a clever trick to quickly identify matching sections, avoiding redundant comparisons.
Here's how the algorithm would work step-by-step:
def longest_happy_prefix(word):
length_of_word = len(word)
prefix_end_index = 0
suffix_start_index = length_of_word - 1
longest_match = ""
# Iterate inward from both ends of the word.
while prefix_end_index < suffix_start_index:
prefix = word[0:prefix_end_index + 1]
suffix = word[suffix_start_index:length_of_word]
# Check if prefix and suffix match.
if prefix == suffix:
# Update the longest match found so far.
longest_match = prefix
# Move pointers inward.
prefix_end_index += 1
suffix_start_index -= 1
return longest_match
Case | How to Handle |
---|---|
Null or empty input string | Return an empty string immediately as there can be no prefix or suffix. |
String of length 1 | Return an empty string as a prefix and suffix cannot overlap in this case. |
String with all identical characters | Iteratively reduce prefix length until a mismatch is found or the prefix is empty. |
Very long string (approaching maximum string length) | Ensure the chosen algorithm (e.g., KMP or rolling hash) is efficient and avoids excessive memory allocation or stack overflow. |
String where the only happy prefix is the empty string | The algorithm should correctly identify and return the empty string as the longest happy prefix when no other match exists. |
String with overlapping prefix and suffix (e.g., 'ababab') | The algorithm should correctly identify the longest overlapping prefix that is also a suffix, handling this overlap properly. |
String containing unicode characters | The algorithm should handle unicode strings correctly, considering that character comparisons may involve multi-byte representations. |
String with maximum length and complex pattern | Ensure the time complexity of the chosen algorithm is optimal (e.g. O(n) using KMP) to handle the maximum input size within acceptable time limits. |