Skip to content

Commit cfe1cf3

Browse files
authored
Create longest-repeating-substring.cpp
1 parent 35061ac commit cfe1cf3

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

C++/longest-repeating-substring.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Time: O(nlogn)
2+
// Space: O(n)
3+
4+
class Solution {
5+
public:
6+
int longestRepeatingSubstring(string S) {
7+
auto left = 1ul, right = S.length() - 1;
8+
while (left <= right) {
9+
const auto mid = left + (right - left) / 2;
10+
if (!check(S, mid)) {
11+
right = mid - 1;
12+
} else {
13+
left = mid + 1;
14+
}
15+
}
16+
return right;
17+
}
18+
19+
private:
20+
uint64_t check(const string& S, uint64_t L) {
21+
static const uint64_t M = 1e9 + 7;
22+
static const uint64_t D = 26;
23+
uint64_t p = power(D, L, M);
24+
uint64_t curr = 0;
25+
for (uint64_t i = 0; i < L; ++i) {
26+
curr = ((D * curr) + S[i] - 'a') % M;
27+
}
28+
unordered_map<uint64_t, vector<uint64_t>> lookup;
29+
lookup[curr].emplace_back(L - 1);
30+
for (uint64_t i = L; i < S.length(); ++i) {
31+
curr = (D * curr) % M;
32+
curr = (curr + (S[i] - 'a')) % M;
33+
curr = (curr + (M - ((S[i - L] - 'a') * p) % M)) % M;
34+
if (lookup.count(curr)) {
35+
for (const auto& j : lookup[curr]) { // check if string is the same when hash is the same
36+
if (S.substr(j - L + 1, L) == S.substr(i - L + 1, L)) {
37+
return i - L + 1;
38+
}
39+
}
40+
}
41+
lookup[curr].emplace_back(i);
42+
}
43+
return 0;
44+
}
45+
46+
uint64_t power(uint64_t D, uint64_t L, uint64_t M) {
47+
uint64_t result = 1;
48+
for (uint64_t i = 0; i < L; ++i) {
49+
result = (result * D) % M;
50+
}
51+
return result;
52+
}
53+
};

0 commit comments

Comments
 (0)