Problem Statement
Given a string, find the length of the longest substring in it with no more than k distinct characters.
Approach: Variable-Size Sliding Window
- Initialize:
windowStart = 0,maxLength = 0, and aHashMapto store character frequencies. - Expand: Move
windowEndforward, adding characters to the map. - Shrink: If the map size exceeds
k, remove characters from thewindowStartuntil the map size iskor less. - Update: Record the maximum window length seen so far.
Java Implementation
import java.util.HashMap;
import java.util.Map;
public int findLongestSubstringWithKDistinct(String str, int k) {
if (str == null || str.length() == 0 || k == 0) return 0;
int windowStart = 0, maxLength = 0;
Map<Character, Integer> charFrequencyMap = new HashMap<>();
for (int windowEnd = 0; windowEnd < str.length(); windowEnd++) {
char rightChar = str.charAt(windowEnd);
charFrequencyMap.put(rightChar, charFrequencyMap.getOrDefault(rightChar, 0) + 1);
// Shrink the window until we have 'k' distinct characters
while (charFrequencyMap.size() > k) {
char leftChar = str.charAt(windowStart);
charFrequencyMap.put(leftChar, charFrequencyMap.get(leftChar) - 1);
if (charFrequencyMap.get(leftChar) == 0) {
charFrequencyMap.remove(leftChar);
}
windowStart++;
}
maxLength = Math.max(maxLength, windowEnd - windowStart + 1);
}
return maxLength;
}
Complexity Discussion
- Time Complexity: $O(n)$. Each character is processed at most twice (once by
windowEndand once bywindowStart). - Space Complexity: $O(k)$ for the frequency map.