Skip to content

Commit 24fe946

Browse files
committed
LongestSubstringWithKDistinctCharacters done
1 parent a4817fe commit 24fe946

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.leetcode.maps.slidingwindow;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
import static org.junit.jupiter.api.Assertions.assertEquals;
7+
8+
/**
9+
* Level: Hard
10+
* Link: https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/
11+
* Description:
12+
* Given a string, find the length of the longest substring T that contains at most k distinct characters.
13+
* <p>
14+
* Example 1:
15+
* Input: s = "eceba", k = 2
16+
* Output: 3
17+
* Explanation: T is "ece" which its length is 3.
18+
* <p>
19+
* Example 2:
20+
* Input: s = "aa", k = 1
21+
* Output: 2
22+
* Explanation: T is "aa" which its length is 2.
23+
*
24+
* @author rampatra
25+
* @since 2019-08-09
26+
*/
27+
public class LongestSubstringWithKDistinctCharacters {
28+
29+
/**
30+
* Time Complexity: O(n)
31+
* Space Complexity: O(k), as we keep at most k characters in the hash table
32+
*
33+
* @param str
34+
* @param k
35+
* @return
36+
*/
37+
public static int lengthOfLongestSubstringKDistinct(String str, int k) {
38+
int length = 0;
39+
Map<Character, Integer> letterCountInWindow = new HashMap<>();
40+
41+
int i = 0; // start of window
42+
int j = i; // end of window
43+
44+
while (j < str.length()) {
45+
char ch = str.charAt(j);
46+
47+
letterCountInWindow.putIfAbsent(ch, 0);
48+
letterCountInWindow.put(ch, letterCountInWindow.get(ch) + 1);
49+
50+
// when number of distinct characters in the window exceeds k:
51+
// - update length
52+
// - remove the first character in the window or reduce its count if the window had more than one of this character
53+
// - lastly, move the window forward
54+
if (letterCountInWindow.keySet().size() > k) {
55+
char firstChar = str.charAt(i);
56+
int firstCharCount = letterCountInWindow.get(firstChar);
57+
if (firstCharCount > 1) {
58+
letterCountInWindow.put(firstChar, firstCharCount - 1);
59+
} else {
60+
letterCountInWindow.remove(firstChar);
61+
}
62+
length = Math.max(length, j - i);
63+
i++;
64+
}
65+
j++;
66+
}
67+
68+
return length == 0 ? j - i : length;
69+
}
70+
71+
public static void main(String[] args) {
72+
assertEquals(3, lengthOfLongestSubstringKDistinct("eceba", 2));
73+
assertEquals(7, lengthOfLongestSubstringKDistinct("eceeeeeba", 2));
74+
assertEquals(2, lengthOfLongestSubstringKDistinct("abcdef", 2));
75+
assertEquals(1, lengthOfLongestSubstringKDistinct("a", 1));
76+
assertEquals(2, lengthOfLongestSubstringKDistinct("aa", 1));
77+
assertEquals(3, lengthOfLongestSubstringKDistinct("aaa", 1));
78+
assertEquals(0, lengthOfLongestSubstringKDistinct("aa", 0));
79+
}
80+
}

0 commit comments

Comments
 (0)