Formatted question description: https://leetcode.ca/all/1392.html

# 1392. Longest Happy Prefix (Hard)

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.


Example 3:

Input: s = "leetcodeleet"
Output: "leet"


Example 4:

Input: s = "a"
Output: ""


Constraints:

• 1 <= s.length <= 10^5
• s contains only lowercase English letters.

Related Topics:
String

## Solution 1. Brute Force with string_view

// OJ: https://leetcode.com/problems/longest-happy-prefix/

// Time: O(N^2)
// Space: O(1)
class Solution {
public:
string longestPrefix(string s) {
int n = s.size();
string_view sv = s;
for(int len = n-1; len>=1; len--){
if (sv.substr(0, len) == sv.substr(n-len))
return s.substr(0, len);
}
return "";
}
};


## Solution 2. Rolling Hash

// OJ: https://leetcode.com/problems/longest-happy-prefix/

// Time: O(N)
// Space: O(1)
// Ref: https://leetcode.com/problems/longest-happy-prefix/discuss/547446/C%2B%2BJava-with-picture-incremental-hash-and-DP
class Solution {
typedef unsigned long long ULL;
public:
string longestPrefix(string s) {
ULL N = s.size(), len = 0, mod = 1e9+7, L = 0 , R = 0, mul = 1;
for (int i = 0; i < N - 1; ++i) {
L = (L * 26 + s[i] - 'a') % mod;
R = (R + mul * (s[N - 1 - i] - 'a')) % mod;
if (L == R) len = i + 1;
mul = mul * 26 % mod;
}
return s.substr(0, len);
}
};


Java

class Solution {
public String longestPrefix(String s) {
if (s == null)
return s;
int length = s.length();
if (length <= 1)
return "";
int[] prefix = prefix(s);
return s.substring(0, prefix[length - 1] + 1);
}

public int[] prefix(String str) {
int length = str.length();
int[] prefix = new int[length];
Arrays.fill(prefix, -1);
int index = -1;
for (int i = 1; i < length; i++) {
while (index >= 0 && str.charAt(index + 1) != str.charAt(i))
index = prefix[index];
if (str.charAt(index + 1) == str.charAt(i))
index++;
prefix[i] = index;
}
return prefix;
}
}