https://leetcode.com/problems/longest-substring-with-at-most-two-distinct-characters/
Given a string, find the length of the longest substring T that contains at most 2 distinct characters.
For example, Given s = “eceba”
,
T is "ece" which its length is 3.
这道题也是一道双指针题,就是在符合条件时不断后移end指针,在不符合条件时前移start指针直到符合条件位置,符合条件后又后移end指针,不断重复循环知道扫描了整个数组。由于各种情况很多,所以双指针题思路一定要特别清楚,知道每个变量的含义是啥,而不是想当然地写代码。
这里面的hashtable里保存的是当前start和end间出现的各种字符的个数,count保存的是start和end间不同字符的个数。
当新加入的end使count变成3后,就前移start,直到count变为2,这时不能忘了也要把新加入的end更新到hashtable里去。
因为它的加入是原来的count从2到3,所以它肯定是之前start和end间没有出现过的数,所以它的次数直接更新为1就行。
public class Solution {
public int lengthOfLongestSubstringTwoDistinct(String s) {
if(s == null) return 0;
if(s.length()<=2) return s.length();
int longest = 2;
int start = 0;
int end = 0;
int count = 0;
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
while(end < s.length()){
char c = s.charAt(end);
if(map.containsKey(c) && map.get(c)>0){
map.put(c, map.get(c)+1);
longest = Math.max(longest, end-start+1);
}
else{
if(count<2){
map.put(c, 1);
count++;
longest = Math.max(longest, end-start+1);
}
else{
map.put(c, 1);
count++;
while(count>2){
map.put(s.charAt(start), map.get(s.charAt(start))-1);
if(map.get(s.charAt(start))==0) count--;
start++;
}
longest = Math.max(longest, end-start+1);
}
}
end++;
}
return longest;
}
}
更新C++代码,这里没有用hash_map结构,但是用了一个256的数组来当作hashmap使用。
class Solution {
public:
int lengthOfLongestSubstringTwoDistinct(string s) {
if(s.size()<=2) return s.size();
int count = 0;
int map[256];
memset(map, 0, sizeof(map)); //注意,数组的初始化
int start = 0;
int end = 0;
int maxlen = 2;
while(end<s.size()){
if(map[s[end]]>0){
map[s[end]]++;
maxlen = std::max(maxlen, end-start+1);
end++;
}
else if(count<2){
map[s[end]]++;
maxlen = std::max(maxlen, end-start+1);
end++;
count++;
}
else{
while(count==2){
map[s[start]]--;
if(map[s[start]]==0) count--;
start++;
}
}
}
return maxlen;
}
};