Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fac15f2

Browse files
authored
Merge pull request ByteByteGoHq#28 from Jer3myYu/java-solutions-sliding-windows
Java Chapter 5: Sliding Windows
2 parents 84cdd7b + e6779ca commit fac15f2

4 files changed

+130
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import java.util.HashSet;
2+
import java.util.Set;
3+
4+
public class LongestSubstringWithUniqueChars {
5+
public int longestSubstringWithUniqueChars(String s) {
6+
int maxLen = 0;
7+
Set<Character> hashSet = new HashSet<>();
8+
int left, right;
9+
left = right = 0;
10+
while (right < s.length()) {
11+
// If we encounter a duplicate character in the window, shrink
12+
// the window until it's no longer a duplicate.
13+
while (hashSet.contains(s.charAt(right))) {
14+
hashSet.remove(s.charAt(left));
15+
left++;
16+
}
17+
// Once there are no more duplicates in the window, update
18+
// 'maxLen' if the current window is larger.
19+
maxLen = Math.max(maxLen, right - left + 1);
20+
hashSet.add(s.charAt(right));
21+
// Expand the window.
22+
right++;
23+
}
24+
return maxLen;
25+
}
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import java.util.HashMap;
2+
import java.util.Map;
3+
4+
public class LongestSubstringWithUniqueCharsOptimized {
5+
public int longestSubstringWithUniqueCharsOptimized(String s) {
6+
int maxLen = 0;
7+
Map<Character, Integer> prevIndexes = new HashMap<>();
8+
int left, right;
9+
left = right = 0;
10+
while (right < s.length()) {
11+
// If a previous index of the current character is present
12+
// in the current window, it's a duplicate character in the
13+
// window.
14+
if (prevIndexes.containsKey(s.charAt(right)) && prevIndexes.get(s.charAt(right)) >= left) {
15+
// Shrink the window to exclude the previous occurrence
16+
// of this character.
17+
left = prevIndexes.get(s.charAt(right)) + 1;
18+
}
19+
// Update 'maxLen' if the current window is larger.
20+
maxLen = Math.max(maxLen, right - left + 1);
21+
prevIndexes.put(s.charAt(right), right);
22+
// Expand the window.
23+
right++;
24+
}
25+
return maxLen;
26+
}
27+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import java.util.HashMap;
2+
import java.util.Map;
3+
4+
public class LongestUniformSubstringAfterReplacements {
5+
public int longestUniformSubstringAfterReplacements(String s, int k) {
6+
Map<Character, Integer> freqs = new HashMap<>();
7+
int highestFreq = 0;
8+
int maxLen = 0;
9+
int left, right;
10+
left = right = 0;
11+
while (right < s.length()) {
12+
// Update the frequency of the character at the right pointer
13+
// and the highest frequency for the current window.
14+
freqs.put(s.charAt(right), freqs.getOrDefault(s.charAt(right), 0) + 1);
15+
highestFreq = Math.max(highestFreq, freqs.get(s.charAt(right)));
16+
// Calculate replacements needed for the current window.
17+
int numCharsToReplace = (right - left + 1) - highestFreq;
18+
// Slide the window if the number of replacements needed exceeds
19+
// 'k'. The right pointer always gets advanced, so we just need
20+
// to advance 'left'.
21+
if (numCharsToReplace > k) {
22+
// Remove the character at the left pointer from the hash map
23+
// before advancing the left pointer.
24+
freqs.put(s.charAt(left), freqs.get(s.charAt(left)) - 1);
25+
left++;
26+
}
27+
// Since the length of the current window increases or stays the
28+
// same, assign the length of the current window to 'maxLen'.
29+
maxLen = right - left + 1;
30+
// Expand the window.
31+
right++;
32+
}
33+
return maxLen;
34+
}
35+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
public class SubstringAnagrams {
2+
public int substringAnagrams(String s, String t) {
3+
int lenS = s.length();
4+
int lenT = t.length();
5+
if (lenT > lenS) return 0;
6+
int count = 0;
7+
int[] expectedFreqs = new int[26];
8+
int[] windowFreqs = new int[26];
9+
// Populate 'expectedFreqs' with the characters in string 't'.
10+
for (char c : t.toCharArray()) {
11+
expectedFreqs[c - 'a']++;
12+
}
13+
int left, right;
14+
left = right = 0;
15+
while (right < lenS) {
16+
// Add the character at the right pointer to 'windowFreqs'
17+
// before sliding the window.
18+
windowFreqs[s.charAt(right) - 'a']++;
19+
// If the window has reached the expected fixed length, we
20+
// advance the left pointer as well as the right pointer to
21+
// slide the window.
22+
if (right - left + 1 == lenT) {
23+
if (compareFreqs(windowFreqs, expectedFreqs)) {
24+
count += 1;
25+
}
26+
// Remove the character at the left pointer from
27+
// 'windowFreqs' before advancing the left pointer.
28+
windowFreqs[s.charAt(left) - 'a']--;
29+
left += 1;
30+
}
31+
right += 1;
32+
}
33+
return count;
34+
}
35+
36+
private boolean compareFreqs(int[] windowFreqs, int[] expectedFreqs) {
37+
for (int i = 0; i < 26; i++) {
38+
if (windowFreqs[i] != expectedFreqs[i]) return false;
39+
}
40+
return true;
41+
}
42+
}

0 commit comments

Comments
 (0)