LeetCode 395. 至少有K个重复的最长子串
题目描述
给你一个字符串 s 和一个整数 k ,请你找出 s 中的最长子串, 要求该子串中的每一字符出现次数都不少于 k 。返回这一子串的长度。
示例1:
输入:s = "aaabb", k = 3
输出:3
解释:最长子串为 "aaa" ,其中 'a' 重复了 3 次。
示例2:
输入:s = "ababbc", k = 2
输出:5
解释:最长子串为 "ababb" ,其中 'a' 重复了 2 次, 'b' 重复了 3 次。
提示:
- 1 <= s.length <= 104
- s仅由小写英文字母组成
- 1 <= k <= 105
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters
思路解析
直接采用暴力枚举的方法不可取,时间复杂度为 \(O(n^3)\),想办法降低时间复杂度。这里采用分治的方法来加速。
- 若某一字符 c在s中出现的次数小于k次,那么可以确定最长的子串一定不包含c,可以将s在所有c出现的地方进行分割,然后计算各个分割得到的子串中符合要求的最大子串。
- 若不存在这样的字符 c,那么直接返回s的长度即可。
代码实现
class Solution {
public:
    int longestSubstring(string s, int k) {
        if(s.empty()) return 0;
        unordered_map<char, vector<int>> smap;
        for(int i = 0; i < s.length(); i++) {
            smap[s[i]].push_back(i);
        }
        for(auto p : smap) {
            if(p.second.size() < k) {
                int maxLen = longestSubstring(s.substr(0, p.second[0]), k);
                for(int i = 0; i < p.second.size(); i++) {
                    int nextPos = (i == p.second.size() - 1) ? s.length() : p.second[i + 1];
                    string tmpStr = s.substr(p.second[i] + 1, nextPos - p.second[i] - 1);
                    int tmpLen = longestSubstring(tmpStr, k);
                    maxLen = max(maxLen, tmpLen);
                }
                return maxLen;
            }
        }
        return s.length();
    }
}; 

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号