Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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
Lines changed: 80 additions & 0 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /