- Longest Substring with At Most K Distinct Characters
Given a string s, find the length of the longest substring T that contains at most k distinct characters.
Example
For example, Given s = “eceba”, k = 3,
T is “eceb” which its length is 4.
Challenge
O(n), n is the size of the string s.
思路:同向双指针。和LintCode 406 (Minimum-Size-Subarray-Sum) 有点象。都是right指针先动,符合条件后,左指针再动,动的过程中必须满足条件。
但区别是406的while()是遍历符合条件(即sum>=s)的left,所以minLen的更新在while()之内。
这题的while()是筛掉不符合条件(即count > k)的left,所以maxLen的更新在while()之外。
两个条件都不需要加l<r或l<=r。
class Solution {
public:
int lengthOfLongestSubstringKDistinct(string s, int k) {
int maxLen = 0;
int l = 0, r = 0;
int len = s.size();
if (len == 0 || k == 0) return 0;
vector<int> dict(256, 0);
int count = 0;
for (int r = 0; r < len; ++r) {
++dict[s[r]];
if (dict[s[r]] == 1) count++;
while (count > k) {
dict[s[l]]--;
if (dict[s[l]] == 0) count--;
++l;
}
maxLen = max(maxLen, r - l + 1);
}
return maxLen;
}
};
二刷:不如上次的代码好。
class Solution {
public:
/**
* @param s: A string
* @param k: An integer
* @return: An integer
*/
int lengthOfLongestSubstringKDistinct(string &s, int k) {
int len = s.size();
int left = 0, right = 0;
unordered_map<char, int> freq;
int maxLen = 0;//, maxLenLeft = 0;
while (left <= right && right < len) {
freq[s[right]]++;
if (freq.size() <= k) {
if (maxLen < right - left + 1) {
maxLen = right - left + 1;
}
}
while (freq.size() > k) {
if (left <= right) {
freq[s[left]]--;
if (freq[s[left]] == 0) freq.erase(s[left]);
left++;
} else {
break;
}
}
right++;
}
return maxLen;
}
};
三刷:这个模板好。
class Solution {
public:
/**
* @param s: a string
* @param k: an integer
* @return: the number of substrings there are that contain at least k distinct characters
*/
long long kDistinctCharacters(string &s, int k) {
int n = s.size();
int left = 0, right = 0;
vector<int> freq(26, 0);
int windowCount = 0;
long long res = 0;
while (right < n) {
char c = s[right] - 'a';
if (freq[c] == 0) windowCount++;
freq[c]++;
right++;
while (left < right && windowCount >= k) {
res += n - right + 1;
c = s[left] - 'a';
freq[c]--;
if (freq[c] == 0) windowCount--;
left++;
}
}
return res;
}
};