forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
maximum-number-of-occurrences-of-a-substring.cpp
83 lines (78 loc) · 2.54 KB
/
maximum-number-of-occurrences-of-a-substring.cpp
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Time: O(n)
// Space: O(n)
// rolling hash (Rabin-Karp Algorithm)
class Solution {
public:
int maxFreq(string s, int maxLetters, int minSize, int maxSize) {
static const uint64_t M = 1000000007;
static const uint64_t p = 113;
uint64_t power = pow(p, minSize - 1, M), rolling_hash = 0;
int left = 0;
unordered_map<int, int> lookup;
unordered_map<char, int> count;
for (int right = 0; right < s.length(); ++right) {
++count[s[right]];
if (right - left + 1 > minSize) {
--count[s[left]];
rolling_hash = (rolling_hash + M - (s[left] * power) % M) % M;
if (!count[s[left]]) {
count.erase(s[left]);
}
++left;
}
rolling_hash = ((rolling_hash * p) % M + s[right]) % M;
if (right - left + 1 == minSize && count.size() <= maxLetters) {
++lookup[rolling_hash];
}
}
return lookup.empty()
? 0
: max_element(lookup.cbegin(), lookup.cend(),
[](const auto& a, const auto& b) {
return a.second < b.second;
})->second;
}
private:
uint64_t pow(uint64_t a,uint64_t b, uint64_t m) {
a %= m;
uint64_t result = 1;
while (b) {
if (b & 1) {
result = (result * a) % m;
}
a = (a * a) % m;
b >>= 1;
}
return result;
}
};
// Time: O(m * n), m = 26
// Space: O(m * n)
class Solution2 {
public:
int maxFreq(string s, int maxLetters, int minSize, int maxSize) {
unordered_map<string, int> lookup;
for (int right = minSize - 1; right < s.length(); ++right) {
const auto& word = s.substr(right - minSize + 1, minSize);
if (lookup.count(word)) {
++lookup[word];
} else if (unique_count(word) <= maxLetters) {
lookup[word] = 1;
}
}
return lookup.empty()
? 0
: max_element(lookup.cbegin(), lookup.cend(),
[](const auto& a, const auto& b) {
return a.second < b.second;
})->second;
}
private:
int unique_count(const string& word) {
unordered_set<char> lookup;
for (const auto& c : word) {
lookup.emplace(c);
}
return lookup.size();
}
};