package com.interview.string;
import java.util.HashMap;
import java.util.Map;
/**
* Date 04/03/2016
* @author Tushar Roy
*
* Given a string, find the length of the longest substring T that contains at most k distinct characters.
* For example, Given s = “eceba” and k = 2,
* T is "ece" which its length is 3.
*
* Time complexity O(n)
* Space complexity O(n)
*
* https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/
*/
public class LongestSubstringWithKDistinctCharacters {
public int lengthOfLongestSubstringKDistinct(String s, int k) {
if (k == 0 || s.length() == 0) {
return 0;
}
int[] ascii = new int[256];
int count = 0;
int start = 0;
int max = 0;
for (int i = 0; i < s.length(); i++) {
int ch = s.charAt(i);
if (count < k) {
if (ascii[ch] == 0) {
count++;
}
} else if (ascii[ch] == 0){
while (start < i) {
char ch1 = s.charAt(start++);
ascii[ch1]--;
if (ascii[ch1] == 0) {
break;
}
}
}
ascii[ch]++;
max = Math.max(max, i - start + 1);
}
return max;
}
public int lengthOfLongestSubstringKDistinctUsingMap(String s, int k) {
if (k == 0 || s.length() == 0) {
return 0;
}
Map<Character, Integer> countMap = new HashMap<>();
int max = 0;
int start = 0;
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (!countMap.containsKey(ch) && countMap.size() >= k) {
while (start < i) {
countMap.compute(s.charAt(start), (key, val) -> {
if (val == 1) {
return null;
} else {
return val - 1;
}
});
start++;
if (countMap.size() < k) {
break;
}
}
}
countMap.compute(ch, (key, val) -> {
if (val == null) {
return 1;
} else {
return val + 1;
}
});
max = Math.max(max, i - start + 1);
}
return max;
}
}