uacs2024

导航

leetcode 1297. 子串的最大出现次数 未解决

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算法

 

posted on 2024-12-03 15:14  ᶜʸᵃⁿ  阅读(12)  评论(0)    收藏  举报