Description:
Find the length of the longest substring T of a given string (consists of lowercase letters only) such that every character in T appears no less than k times.
Example 1:
Input:
s = "aaabb", k = 3
Output:
3
The longest substring is "aaa", as 'a' is repeated 3 times.
Example 2:
Input:
s = "ababbc", k = 2
Output:
5
The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.
———————————————————————————————————————————————————
Solution:
題意:給定一個字符串,返回一個所有字符出現次數都不小於k的子字符串最大長度。
思路:
【TLE】1.暴力循環法:
class Solution {
public:
int longestSubstring(string s, int k) {
if (s.length() < k)
return 0;
int maxLength = 0;
for (int start = 0, tempMax = k; start < s.length() - tempMax + 1; start++) {
//cout << start << " <-start- ";
map<char, int> window;
set<char> invalidChar;
for (int i = start; i < start + tempMax; i++)
window[s[i]]++;
for (map<char, int>::iterator it = window.begin(); it != window.end(); it++)
if (it->second < k)
invalidChar.insert(it->first);
maxLength = invalidChar.size() == 0 ? max(maxLength, k) : maxLength;
for (int end = start + tempMax; end < s.length(); end++) {
//cout << end << " ";
if (++window[s[end]] < k)
invalidChar.insert(s[end]);
else if (invalidChar.find(s[end]) != invalidChar.end())
invalidChar.erase(s[end]);
if (invalidChar.size() == 0)
maxLength = max(maxLength, end - start + 1);
}
tempMax = max(tempMax, maxLength);
//cout << " -maxLength-> " << maxLength << endl;
}
return maxLength;
}
};
class Solution {
public:
int longestSubstring(string s, int k) {
/*
1. in the first pass I record counts of every character in a hashmap
2. in the second pass I locate the first character that appear less than k times in the string. this character is definitely not included in the result, and that separates the string into two parts.
3. keep doing this recursively and the maximum of the left/right part is the answer.
*/
if (s.length() == 0 || k > s.length())
return 0;
if (k == 0)
return s.length();
map<char, int> frequency;
for (int i = 0; i < s.length(); i++)
frequency[s[i]]++;
int first = 0;
while (first < s.length() && frequency[s[first]] >= k)
first++;
if (first == s.length())
return s.length();
int second = first + 1;
while (second < s.length() && frequency[s[second]] < k)
second++;
return second == s.length() ? longestSubstring(s.substr(0, first), k) : max(longestSubstring(s.substr(0, first), k), longestSubstring(s.substr(second), k));
}
};