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.
Naive Solution: try every possible substring
Time complexity: O(n^2)
public int lengthOfLongestSubstringTwoDistinct(String s) {
int maxLength = 0;
for (int i = 0; i < s.length(); i++) {
Set<Character> set = new HashSet();
int length = 0;
// test each substring start from j = i
for (int j = i; j < s.length(); j++) {
length++;
if (!set.contains(s.charAt(j))) {
set.add(s.charAt(j));
if (set.size() == 3) {
length--;
break;
}
}
}
maxLength = Math.max(maxLength, length);
}
return maxLength;
}
Time complexity: O(n * 2)
public int lengthOfLongestSubstringTwoDistinct(String s) {
int maxLength = 0 ;
Map<Character, Integer> map = new HashMap();
int left = 0;
for (int i = 0; i < s.length(); i++) {
// when we meet the third unique character
if (map.size() == 2 && !map.containsKey(s.charAt(i))) {
int length = i - left;
maxLength = Math.max(length, maxLength);
int leftMostIndex = Integer.MAX_VALUE;
// find the left most character
for (Character c : map.keySet()) {
if (map.get(c) < leftMostIndex) {
leftMostIndex = map.get(c);
}
}
left = leftMostIndex + 1; // set the left index to be the one deleted plus one
// remove the left most index from the map
map.remove(s.charAt(leftMostIndex));
}
map.put(s.charAt(i), i);
}
maxLength = Math.max(maxLength, s.length() -left); // handle the last case
if (map.size() <= 2 && maxLength == 0) {
return s.length();
}
return maxLength;
}