方法一:
int lengthOfLongestSubstringTwoDistinct(string s) {
unordered_map<char, int> sHT; //滑动窗口的哈希表
//key值为所包含的字符,value值为出现的次数
int left = 0, right = 0, L = 0,hTsize=0,sLength=s.length();
//左右边界指针,子串长度,哈希表大小,字符串长度
sHT[s[0]]++;
while (right < sLength) {
hTsize = sHT.size();
if (hTsize <= 2) {
L = max(L, right - left + 1);
if (right + 1 < sLength) {
sHT[s[++right]]++;
}
else {
break;
}
}
else {
if (sHT[s[left]] == 1) {
sHT.erase(s[left]);
}
else if(sHT[s[left]] > 1){
sHT[s[left]]--;
}
left++;
}
}
return L;
}
方法二:
int lengthOfLongestSubstringTwoDistinct(string s) {
int strLength = s.length();
if (strLength < 3) return strLength;
int left = 0;
int right = 0;
unordered_map<char, int> map; //key为字符,value为其出现的下标
int maxLen = 2;
while (right < strLength) {
map[s[right]] = right; //将右边界的字符放入滑动窗口中,并存储其自身及其下标与哈希表中
right++;
if (map.size() > 2) { //滑动窗口内字符多于2个,左边界收缩
//且不是简单地+1,所以时间效率更高!!!!
unordered_map<char, int>::iterator it = map.begin();
char delChar = it->first;
int delIndex = it->second;
while (++it != map.end()) {
if (it->second < delIndex) {
delChar = it->first;
delIndex = it->second;
}
}
map.erase(delChar);
left = delIndex + 1;
//找到下标最小的迭代器,让左边界跳转到对应second+1处
}
else if (map.size() == 2) {
//只有滑动窗口内字符种类等于2,才需要更新子串长度
maxLen = max(maxLen, right - left);
}
}
return maxLen;
}
两种方法时间效率都是O(n),但是方法二左边界收缩不是单纯地前进一位,而是根据下标最小值,直接跳转到该最小值后一位,所以时间效率更高!!!!