[LeetCode] Longest Duplicate Substring

1044. Longest Duplicate Substring

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 “”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class Solution {
vector<long> power;
int mod = 1e9 + 7;
string rabinKarp(int len, string& s) {
if(len == 0) return "";
long hash = 0;
unordered_map<long, vector<pair<int, string>>> lookup;
for(int i = 0; i < len; i++) {
hash = (hash * 26 + (s[i] - 'a')) % mod;
}
lookup[hash].push_back({0, ""});
for(int i = len; i < s.length(); i++) {
hash = ((hash - power[len - 1] * (s[i-len] - 'a')) % mod + mod) % mod; //remove
hash = (hash * 26 + (s[i] - 'a')) % mod;
string subString = "";
if(lookup.count(hash)) {
subString = s.substr(i - len + 1, len);
for(int j = 0; j < lookup[hash].size(); j++) {
if(lookup[hash][j].second == "") {
lookup[hash][j].second = s.substr(lookup[hash][j].first, len);
}
if(lookup[hash][j].second == subString)
return subString;
}
}
lookup[hash].push_back({i - len + 1, subString});
}
return "";
}
public:
string longestDupSubstring(string s) {
int l = 0, r = s.length();
power = vector<long>(r, 1);
for(int i = 1; i < r; i++)
power[i] = power[i-1] * 26 % mod;
string res = "";
while(l <= r) {
int m = l + (r - l) / 2;
string cmp;
if(m == l and l + 1 == r) {
cmp = rabinKarp(m + 1, s);
if(cmp.length() == 0)
cmp = rabinKarp(m,s);
} else {
cmp = rabinKarp(m, s);
}
if(cmp.length() > 0) {
l = m + 1;
if(res.length() < cmp.length())
res = cmp;
} else {
r = m - 1;
}
}
return res;
}
};
Author: Song Hayoung
Link: https://songhayoung.github.io/2022/03/12/PS/LeetCode/longest-duplicate-substring/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.