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.
Understand the problem:
The problem looks quite similar to a previous problem:
The idea is still to use two pointers, i and j. We move the pointer i forward and put the visited character as well as its times into a map. We also need to increase the counter if the character is not in the map.
When the counter is greater than 2, we need to move the second pointer j and try to decrease the counter. However, we cannot just decrease the counter by 1 once we move the j pointer a step forward. e.g. b e c e a. When the i pointer is at a, and j pointer is at e, move the j pointer from e to c does not decrease the counter (still 3). Therefore, the condition to decrease the counter is when the character is not in the map again.
Code (Java):
public class Solution {
public int lengthOfLongestSubstringTwoDistinct(String s) {
if (s == null || s.length() < 3) {
return s.length();
}
Map<Character, Integer> map = new HashMap<Character, Integer>();
int maxLen = 0;
int j = 0;
int counter = 0;
for (int i = 0; i < s.length(); i++) {
char element = s.charAt(i);
if (!map.containsKey(element)) {
counter++;
map.put(element, 1);
while (j < i && counter > 2) {
if (map.get(s.charAt(j)) == 1) {
map.remove(s.charAt(j));
} else {
int tmp = map.get(s.charAt(j)) - 1;
map.put(s.charAt(j), tmp);
}
if (!map.containsKey(s.charAt(j))) {
counter--;
}
j++;
}
} else {
int tmp = map.get(s.charAt(i));
map.put(s.charAt(i), tmp + 1);
}
maxLen = Math.max(maxLen, i - j + 1);
}
return maxLen;
}
}
Analysis:
Time complexity is O(n) since we only move the pointers forward. The space complexity is at O(k) where k the number of distinct numbers in the substring. In this case, k is 2.
Update on 10/13/15:
public class Solution {
public int lengthOfLongestSubstringTwoDistinct(String s) {
if (s == null || s.length() == 0) {
return 0;
}
Map<Character, Integer> map = new HashMap<>();
int j = 0;
int i = 0;
int len = 0;
for (i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (!map.containsKey(c)) {
map.put(c, i);
} else {
int pos = map.get(c);
map.put(c, i);
}
if (map.size() > 2) {
len = Math.max(len, i - j);
// Then shrink the window size
while (map.size() > 2) {
if (map.containsKey(s.charAt(j)) && map.get(s.charAt(j)) == j) {
map.remove(s.charAt(j));
}
j++;
}
}
}
if (j < s.length()) {
len = Math.max(len, i - j);
}
return len;
}
}
No comments:
Post a Comment