Skip to content

Commit a1fada8

Browse files
add a solution for 395
1 parent cff8014 commit a1fada8

File tree

2 files changed

+101
-5
lines changed

2 files changed

+101
-5
lines changed

src/main/java/com/fishercoder/solutions/_395.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,63 @@ int findLongestSubstring(char[] chars, int start, int end, int k) {
3737
return end - start;
3838
}
3939
}
40+
41+
public static class Solution2 {
42+
/**
43+
* classic sliding window approach.
44+
* credit: https://leetcode.com/problems/longest-substring-with-at-least-k-repeating-characters/discuss/170010/Java-O(n)-Solution-with-Detailed-Explanation-Sliding-Window/774350
45+
*/
46+
public int longestSubstring(String s, int k) {
47+
int res = 0;
48+
for (int numUniqueTarget = 1; numUniqueTarget <= 26; numUniqueTarget++) {
49+
res = Math.max(res, slidingWindowHelper(s, k, numUniqueTarget));
50+
}
51+
return res;
52+
}
53+
54+
// sliding window template
55+
private int slidingWindowHelper(String s, int k, int numUniqueTarget) {
56+
int[] map = new int[26];
57+
int start = 0;
58+
int end = 0;
59+
int res = 0;
60+
int uniqueLetterCount = 0;
61+
int numNoLessThanK = 0;
62+
while (end < s.length()) {
63+
char c1 = s.charAt(end);
64+
if (map[c1 - 'a'] == 0) {
65+
//we increment this when we include a new letter into our sliding window
66+
uniqueLetterCount++;
67+
}
68+
map[c1 - 'a']++;
69+
if (map[c1 - 'a'] == k) {
70+
//we increment this number when we find a letter's frequency reaches k
71+
numNoLessThanK++;
72+
}
73+
end++;
74+
75+
while (uniqueLetterCount > numUniqueTarget) {
76+
//as long as the counter (the number of qualified letters) is greater than our target number,
77+
//we can move the left pointer to the right,
78+
//this keeps the interval within our sliding window always valid
79+
char c2 = s.charAt(start);
80+
if (map[c2 - 'a'] == k) {
81+
//we decrement this numNoLessThanK when we find this letter's frequency equals
82+
//to k because we'll move past this letter, i.e. our sliding window no longer includes it
83+
numNoLessThanK--;
84+
}
85+
map[c2 - 'a']--;
86+
if (map[c2 - 'a'] == 0) {
87+
uniqueLetterCount--;
88+
}
89+
start++;
90+
}
91+
92+
if (uniqueLetterCount == numNoLessThanK) {
93+
res = Math.max(res, end - start);
94+
}
95+
}
96+
return res;
97+
}
98+
}
4099
}

src/test/java/com/fishercoder/_395Test.java

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,63 @@
66

77
import static junit.framework.Assert.assertEquals;
88

9-
/**
10-
* Created by fishercoder on 12/31/16.
11-
*/
129
public class _395Test {
1310

1411
private static _395.Solution1 solution1;
12+
private static _395.Solution2 solution2;
13+
private static String s;
14+
private static int k;
15+
private static int expected;
1516

1617
@BeforeClass
1718
public static void setup() {
1819
solution1 = new _395.Solution1();
20+
solution2 = new _395.Solution2();
1921
}
2022

2123
@Test
2224
public void test1() {
23-
assertEquals(5, solution1.longestSubstring("ababbc", 2));
25+
s = "ababbc";
26+
expected = 5;
27+
k = 2;
28+
assertEquals(expected, solution1.longestSubstring(s, k));
29+
assertEquals(expected, solution2.longestSubstring(s, k));
2430
}
2531

2632
@Test
2733
public void test2() {
28-
assertEquals(3, solution1.longestSubstring("aaabb", 3));
34+
s = "aaabb";
35+
k = 3;
36+
expected = 3;
37+
assertEquals(expected, solution1.longestSubstring(s, k));
38+
assertEquals(expected, solution2.longestSubstring(s, k));
39+
}
40+
41+
@Test
42+
public void test3() {
43+
s = "bbaaacbd";
44+
k = 3;
45+
expected = 3;
46+
assertEquals(expected, solution1.longestSubstring(s, k));
47+
assertEquals(expected, solution2.longestSubstring(s, k));
48+
}
49+
50+
@Test
51+
public void test4() {
52+
s = "weitong";
53+
k = 2;
54+
expected = 0;
55+
assertEquals(expected, solution1.longestSubstring(s, k));
56+
assertEquals(expected, solution2.longestSubstring(s, k));
57+
}
58+
59+
@Test
60+
public void test5() {
61+
s = "a";
62+
k = 2;
63+
expected = 0;
64+
assertEquals(expected, solution1.longestSubstring(s, k));
65+
assertEquals(expected, solution2.longestSubstring(s, k));
2966
}
3067

3168
}

0 commit comments

Comments
 (0)