Skip to content

Commit 0184b75

Browse files
committed
ts-5: add sliding windows solutions
1 parent d03d5c7 commit 0184b75

4 files changed

+100
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function longestSubstringWithUniqueChars(s: string): number {
2+
let maxLen = 0;
3+
let hashSet: Set<string> = new Set();
4+
let left = 0, right = 0;
5+
while(right < s.length) {
6+
// If we encounter a duplicate character in the window, shrink
7+
// the window until it's no longer a duplicate.
8+
while(hashSet.has(s[right])){
9+
hashSet.delete(s[left]);
10+
left++;
11+
}
12+
// Once there are no more duplicates in the window, update
13+
// 'maxLen' if the current window is larger.
14+
maxLen = Math.max(maxLen, right - left + 1);
15+
hashSet.add(s[right]);
16+
// Expand the window.
17+
right++;
18+
}
19+
return maxLen;
20+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function longestSubstringWithUniqueCharsOptimized(s: string): number {
2+
let maxLen = 0;
3+
let prevIndexes: { [key: string]: number } = {};
4+
let left = 0, right = 0;
5+
while(right < s.length) {
6+
// If a previous index of the current character is present
7+
// in the current window, it's a duplicate character in the
8+
// window.
9+
if (prevIndexes[s[right]] !== undefined
10+
&& prevIndexes[s[right]] >= left) {
11+
// Shrink the window to exclude the previous occurrence
12+
// of this character.
13+
left = prevIndexes[s[right]] + 1;
14+
}
15+
// Update 'maxLen' if the current window is larger.
16+
maxLen = Math.max(maxLen, right - left + 1);
17+
prevIndexes[s[right]] = right;
18+
// Expand the window.
19+
right++;
20+
}
21+
return maxLen;
22+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
function longestUniformSubstringAfterReplacements(s: string, k: number): number {
2+
const freqs: { [key: string]: number } = {};
3+
let highestFreq = 0, maxLen = 0;
4+
let left = 0, right = 0;
5+
while (right < s.length) {
6+
// Update the frequency of the character at the right pointer
7+
// and the highest frequency for the current window.
8+
freqs[s[right]] = (freqs[s[right]] || 0) + 1;
9+
highestFreq = Math.max(highestFreq, freqs[s[right]]);
10+
// Calculate replacements needed for the current window.
11+
const numCharsToReplace = (right - left + 1) - highestFreq;
12+
// Slide the window if the number of replacements needed exceeds
13+
// 'k'. The right pointer always gets advanced, so we just need
14+
// to advance 'left'.
15+
if (numCharsToReplace > k) {
16+
// Remove the character at the left pointer from the hash map
17+
// before advancing the left pointer.
18+
freqs[s[left]]--;
19+
left++;
20+
}
21+
// Since the length of the current window increases or stays the
22+
// same, assign the length of the current window to 'maxLen'.
23+
maxLen = right - left + 1;
24+
// Expand the window.
25+
right++;
26+
}
27+
return maxLen;
28+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
function substringAnagrams(s: string, t: string): number {
2+
const lenS = s.length, lenT = t.length;
3+
if (lenT > lenS)
4+
return 0;
5+
let count = 0;
6+
const expectedFreqs = new Array(26).fill(0);
7+
const windowFreqs = new Array(26).fill(0);
8+
// Populate 'expected_freqs' with the characters in string 't'.
9+
for (const c of t)
10+
expectedFreqs[c.charCodeAt(0) - 'a'.charCodeAt(0)]++;
11+
let left = 0, right = 0;
12+
while (right < lenS) {
13+
// Add the character at the right pointer to 'window_freqs'
14+
// before sliding the window.
15+
windowFreqs[s[right].charCodeAt(0) - 'a'.charCodeAt(0)]++;
16+
// If the window has reached the expected fixed length, we
17+
// advance the left pointer as well as the right pointer to
18+
// slide the window.
19+
if (right - left + 1 === lenT) {
20+
if (windowFreqs.every((val, i) => val === expectedFreqs[i]))
21+
count++;
22+
// Remove the character at the left pointer from
23+
// 'window_freqs' before advancing the left pointer.
24+
windowFreqs[s[left].charCodeAt(0) - 'a'.charCodeAt(0)]--;
25+
left++;
26+
}
27+
right++;
28+
}
29+
return count;
30+
}

0 commit comments

Comments
 (0)