leetcode 1297. 子串的最大出现次数 未解决
暴力解,超时🤡
class Solution {
public:
int maxFreq(string s, int maxLetters, int minSize, int maxSize) {
int size = s.size(), maxRes = 0;
unordered_map<string,int> stringAdded;
for(int i = 0;i <= size - maxSize;i++){
for(int j = minSize;j <= maxSize ;j++){
string temp = move(s.substr(i,j));
unordered_map<char,int> letterAdded;
for(int k = 0;k < j;k++) letterAdded[temp[k]]++;
if(letterAdded.size() <= maxLetters) stringAdded[temp]++;
maxRes = max(maxRes,stringAdded[temp]);
}
}
for(int i = size - maxSize + 1;i <= size - minSize;i++){
for(int j = minSize;i + j <= size;j++){
string temp = move(s.substr(i,j));
unordered_map<char,int> letterAdded;
for(int k = 0;k < j;k++) letterAdded[temp[k]]++;
if(letterAdded.size() <= maxLetters) stringAdded[temp]++;
maxRes = max(maxRes,stringAdded[temp]);
}
}
return maxRes;
}
};
法一:枚举。用时1249ms,内存264.65MB
class Solution {
public:
int maxFreq(string s, int maxLetters, int minSize, int maxSize) {
int size = s.size(), maxRes = 0;
unordered_map<string,int> stringAdded;
for(int i = 0;i < size;i++){
unordered_set<char> letterAdded;
string str;
for(int j = i;j < min(size,i + maxSize);j++){
letterAdded.insert(s[j]);
//如果字母类别数已超过了maxLetters,后面还没到maxSize长度的子串不用判断了,直接break,可以节省很多时间
if(letterAdded.size() > maxLetters) break;
str += s[j];
if(j - i + 1 >= minSize){
stringAdded[str]++;
if(stringAdded[str] > maxRes) maxRes = stringAdded[str];
}
}
}
return maxRes;
}
};
法二:可行性优化。只需枚举所有长度为minSize的字符串
class Solution {
public:
int maxFreq(string s, int maxLetters, int minSize, int maxSize) {
int size = s.size(), maxRes = 0;
unordered_map<string,int> stringAdded;
//假设字符串 T 在给定的字符串 S 中出现的次数为 k,那么 T 的任意一个子串出现的次数至少也为 k,
//即 T 的任意一个子串在 S 中出现的次数不会少于 T 本身。
//这样可以断定,在所有满足条件且出现次数最多的的字符串中,一定有一个的长度恰好为 minSize。
//比如有一个长度为 k 的字符串 str 满足条件且出现次数 n 为最多,其中 minSize <= k <= maxSize
//那么 str 的所有长度 len 为minSize <= len <= k 的子串在整个字符串 S 中出现次数至少为 n 次
//所以只需要枚举所有长度为 minSize 的字符串即可
for(int i = 0;i < size - minSize + 1;i++){
string str = move(s.substr(i,minSize));
unordered_set<char> letterAdded(str.begin(),str.end());
if(letterAdded.size() <= maxLetters){
stringAdded[str]++;
if(stringAdded[str] > maxRes) maxRes = stringAdded[str];
}
}
return maxRes;
}
};
法三:滚动哈希、Rabin-Karp算法