Problem Description:
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.
This problem has a very straight-forward solution. We maintain an unordered_set st to record the unique characters we have met, an integer len to record the length of the substring.
Then we start to traverse the string from beinning to end. Each time we meet a character, if the size of st is less than 2 or its size is equal to 2 but the current character is in st (so adding it to the substring will still give only 2 distinct characters), we insert the character into st and increment len by 1.
The tricky case happens when the above underlined contition is violated. When it is violated, we know the substring needs to be changed. We reset len to 0 and clear st. Then we add the current character into st and increment len by 1. However, we cannot move forwards immediately now. We meed to move backwards to the beginning of the string and try to add as many characters as the underlined condition is not violated. Only after which we will move forwards as before.
If you feel confused, please consider the example "abcc". Once you add a and b into st and meet c, you clear st and add c into it. Then if you go forwards, you add the second c into s and you will conclude the longest length is 2. However, the answer is "bcc", which is of length 3. So after you add the first c, you need to move backwards and add b into st(you cannot move backwards and add a because it will violate the underlined condition), after which will you go forward to add the second c.
The code is as follows. You may try it on "abcc" to see how it works.
1 int lengthOfLongestSubstringTwoDistinct(string s) { 2 int len = 0, maxlen = 0; 3 unordered_set<char> st; 4 for (int i = 0; i < (int)s.length();) { 5 if (st.size() < 2 || (st.size() == 2 && st.find(s[i]) != st.end())) { 6 st.insert(s[i++]); 7 len++; 8 } 9 else { 10 maxlen = max(maxlen, len); 11 st.clear(); 12 int pos = i; 13 st.insert(s[i--]); 14 len = 1; 15 while (i && (st.size() < 2 || (st.size() == 2 && st.find(s[i]) != st.end()))) { 16 st.insert(s[i--]); 17 len++; 18 } 19 i = pos + 1; 20 } 21 } 22 return max(maxlen, len); 23 }