
About the author
Mallikarjuna Mallisetty
General programming
Mallikarjuna shares practical programming tutorials and foundational concepts designed to help developers learn by building and experimenting.
View LinkedIn profile ↗#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define MAX_CHAR 256
int longestSubstringKDistinct(const char* s, int k) {
if (k == 0 || s[0] == '\0') return 0;
int freq[MAX_CHAR] = {0};
int distinctCount = 0, maxLen = 0;
int start = 0, end = 0, len = strlen(s);
while (end < len) {
if (freq[(unsigned char)s[end]] == 0) distinctCount++;
freq[(unsigned char)s[end]]++;
while (distinctCount > k) {
freq[(unsigned char)s[start]]--;
if (freq[(unsigned char)s[start]] == 0) distinctCount--;
start++;
}
int windowLen = end - start + 1;
if (windowLen > maxLen) maxLen = windowLen;
end++;
}
return maxLen;
}
int main() {
const char* s1 = "eceba";
int k1 = 2;
printf("Longest substring length for '%s' with at most %d distinct chars: %d\n", s1, k1, longestSubstringKDistinct(s1, k1));
const char* s2 = "aa";
int k2 = 1;
printf("Longest substring length for '%s' with at most %d distinct chars: %d\n", s2, k2, longestSubstringKDistinct(s2, k2));
return 0;
}| Case | Time Complexity | Explanation |
|---|---|---|
| Best Case | O(n) | Even in the best case (e.g., when the entire string already has ≤ k distinct characters), the algorithm must traverse the entire string once using the end pointer to build the sliding window. |
| Average Case | O(n) | On average, each character is added and removed from the hash map at most once, and the window adjusts accordingly — leading to a linear pass through the string. |
| Worst Case | O(n) | Even in the worst case (when the character set frequently exceeds k), the sliding window still ensures that each character is processed at most twice — once when added and once when removed — resulting in linear time. |