思路:
尺取法。
循环i:1~26,分别计算恰好包含i种字母并且每种字母出现的次数大于等于k个的最长子串长度。
没法直接使用尺取法,因为不满足区间单调性,但是使用如上的方法却是可以的,因为子串中包含的字母种类数是满足区间单调性的。
实现:
1 #include <bits/stdc++.h> 2 using namespace std; 3 class Solution 4 { 5 public: 6 int longestSubstring(string s, int k) 7 { 8 int n = s.length(); 9 if (k == 1) return n; 10 int ans = 0; 11 vector<int> num(26, 0); 12 for (int i = 1; i <= 26; i++) 13 { 14 fill(num.begin(), num.end(), 0); 15 int slow = 0, fast = 0, cnt = 0; 16 set<char> st; 17 while (fast < n) 18 { 19 while (fast < n) 20 { 21 if (num[s[fast] - 'a'] == 0) cnt++; 22 num[s[fast] - 'a']++; 23 st.insert(s[fast]); 24 fast++; 25 if (cnt == i && fast < n && num[s[fast] - 'a'] == 0) 26 break; 27 } 28 bool flg = true; 29 for (auto it: st) 30 if (num[it - 'a'] < k) { flg = false; break; } 31 if (flg) ans = max(ans, fast - slow); 32 if (fast == n) break; 33 while (slow < fast && cnt == i) 34 { 35 num[s[slow] - 'a']--; 36 if (num[s[slow] - 'a'] == 0) { cnt--; st.erase(s[slow]); } 37 slow++; 38 } 39 } 40 } 41 return ans; 42 } 43 }; 44 int main() 45 { 46 string s = "aabbccdcccde"; int k = 2; 47 cout << Solution().longestSubstring(s, k) << endl; 48 return 0; 49 }