Skip to content

Commit 012ee57

Browse files
committed
Add Longest Substring with K Distinct Characters sliding window algorithm with tests
1 parent f693c44 commit 012ee57

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.thealgorithms.strings;
2+
3+
import java.util.HashMap;
4+
5+
public class LongestSubstringKDistinct {
6+
7+
/**
8+
* Returns the length of the longest substring that contains
9+
* at most k distinct characters.
10+
*
11+
* Sliding Window + HashMap
12+
* Time Complexity: O(n)
13+
* Space Complexity: O(k)
14+
*/
15+
public static int longestSubstringKDistinct(String s, int k) {
16+
if (k == 0 || s == null || s.isEmpty()) {
17+
return 0;
18+
}
19+
20+
int left = 0, maxLen = 0;
21+
HashMap<Character, Integer> map = new HashMap<>();
22+
23+
for (int right = 0; right < s.length(); right++) {
24+
char ch = s.charAt(right);
25+
map.put(ch, map.getOrDefault(ch, 0) + 1);
26+
27+
while (map.size() > k) {
28+
char leftChar = s.charAt(left);
29+
map.put(leftChar, map.get(leftChar) - 1);
30+
31+
if (map.get(leftChar) == 0) {
32+
map.remove(leftChar);
33+
}
34+
left++;
35+
}
36+
37+
maxLen = Math.max(maxLen, right - left + 1);
38+
}
39+
40+
return maxLen;
41+
}
42+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.thealgorithms.strings;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
public class LongestSubstringKDistinctTest {
8+
9+
@Test
10+
void testBasic() {
11+
assertEquals(3, LongestSubstringKDistinct.longestSubstringKDistinct("eceba", 2));
12+
assertEquals(2, LongestSubstringKDistinct.longestSubstringKDistinct("aa", 1));
13+
}
14+
15+
@Test
16+
void testEdgeCases() {
17+
assertEquals(0, LongestSubstringKDistinct.longestSubstringKDistinct("", 2));
18+
assertEquals(0, LongestSubstringKDistinct.longestSubstringKDistinct("abc", 0));
19+
}
20+
21+
@Test
22+
void testLarge() {
23+
assertEquals(4, LongestSubstringKDistinct.longestSubstringKDistinct("aabbcc", 2));
24+
assertEquals(6, LongestSubstringKDistinct.longestSubstringKDistinct("abcabcbb", 3));
25+
}
26+
}

0 commit comments

Comments
 (0)