Given a string S
, consider all duplicated substrings: (contiguous) substrings of S that occur 2 or more times. (The occurrences may overlap.)
Return any duplicated substring that has the longest possible length. (If S
does not have a duplicated substring, the answer is ""
.)
Example 1:
Input: "banana" Output: "ana"
Example 2:
Input: "abcd" Output: ""
Note:
2 <= S.length <= 10^5
S
consists of lowercase English letters.
class Solution {
public:
string longestDupSubstring(string S)
{
int low = 1 , high = S.size() ;
string res = "" ;
base = vector<long long>(high , 1) ;
for(int i = 1 ; i < high ; ++i)
base[i] = ( base[i - 1] * 26 ) % modl ;
while(low < high)
{
int mid = low + (high - low) / 2 ;
string ans = search(mid , S) ;
if(ans.empty())
{
high = mid ;
}
else
{
if(ans.size() > res.size())
res = ans ;
low = mid + 1 ;
}
}
return res ;
}
private :
int modl = 1000000007 ; //为什么错误会出现在这里?
vector<long long> base ;
string search(int len , string S)
{
if(len == 0) return "" ;
unordered_map<int , vector<int>> substr_hash ;
long long cur = 0 ;
for(int i = 0 ; i < len ; i++)
cur = ( (cur * 26) % modl + (S[i] - 'a') ) % modl ;
substr_hash[cur] = vector<int>(1 , 0) ;
for(int i = len ; i < S.size() ; i++)
{
cur = (cur - ((S[i - len] - 'a') * base[len - 1]) % modl + modl) % modl ; //因为cur是取模后的值,而(S[i - len] - 'a') * base[len - 1]的值可能会超过modl,所以要先对其取模,因为cur与其相减可能会变成复数,所以先加上modl再取模;
cur = (cur * 26 + (S[i] - 'a')) % modl ;
if(!substr_hash.count(cur))
{
substr_hash[cur] = vector<int>(1 , i - len + 1) ;
}
else
{
for(auto ele : substr_hash[cur])
{
if(strcmp(S.substr(ele , len).c_str() , S.substr(i - len + 1 , len).c_str()) == 0)
return S.substr(ele , len) ;
}
substr_hash[cur].push_back(i - len + 1) ;
}
}
return "" ;
}
};