Skip to content

Commit 0d870b2

Browse files
committed
LeetCode Longest Substring With At Most K Distinct Characters
1 parent c1b5a71 commit 0d870b2

File tree

5 files changed

+49
-109
lines changed

5 files changed

+49
-109
lines changed

0340-longest-substring-with-at-most-k-distinct-characters/README.md

Lines changed: 0 additions & 30 deletions
This file was deleted.

0340-longest-substring-with-at-most-k-distinct-characters/longest-substring-with-at-most-k-distinct-characters.ts

Lines changed: 0 additions & 36 deletions
This file was deleted.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ A comprehensive collection of coding challenges from multiple platforms for lear
328328
- [0003 - Longest Substring Without Repeating Characters](./leetcode/medium/0003-longest-substring-without-repeating-characters) - Medium
329329
- [0159 - Longest Substring with At Most Two Distinct Characters](./leetcode/medium/0159-longest-substring-with-at-most-two-distinct-characters) - Medium
330330
- [0209 - Minimum Size Subarray Sum](./leetcode/medium/0209-minimum-size-subarray-sum) - Medium
331+
- [0340 - Longest Substring with At Most K Distinct Characters](./leetcode/medium/0340-longest-substring-with-at-most-k-distinct-characters) - Medium
331332
- [More in docs →](./docs/techniques/SLIDING_WINDOW.md)
332333

333334
### Hash Table / Hash Map
Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,24 @@
1+
# [Longest Substring with At Most K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters) ![Medium](https://img.shields.io/badge/Medium-orange)
12

2-
# [Longest Substring with At Most K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters) ![](https://img.shields.io/badge/Medium-orange)
3+
Given a string `s` and an integer `k`, return _the length of the longest **substring** of_ `s` _that contains at most_ `k` _**distinct** characters_.
34

4-
<p>Given a string <code>s</code> and an integer <code>k</code>, return <em>the length of the longest </em><span data-keyword="substring-nonempty"><em>substring</em></span><em> of</em> <code>s</code> <em>that contains at most</em> <code>k</code> <em><strong>distinct</strong> characters</em>.</p>
5+
## Example 1
56

6-
<p>&nbsp;</p>
7-
<p><strong class="example">Example 1:</strong></p>
7+
```text
8+
Input: s = "eceba", k = 2
9+
Output: 3
10+
Explanation: The substring is "ece" with length 3.
11+
```
812

9-
<pre>
10-
<strong>Input:</strong> s = &quot;eceba&quot;, k = 2
11-
<strong>Output:</strong> 3
12-
<strong>Explanation:</strong> The substring is &quot;ece&quot; with length 3.</pre>
13+
## Example 2
1314

14-
<p><strong class="example">Example 2:</strong></p>
15+
```text
16+
Input: s = "aa", k = 1
17+
Output: 2
18+
Explanation: The substring is "aa" with length 2.
19+
```
1520

16-
<pre>
17-
<strong>Input:</strong> s = &quot;aa&quot;, k = 1
18-
<strong>Output:</strong> 2
19-
<strong>Explanation:</strong> The substring is &quot;aa&quot; with length 2.
20-
</pre>
21+
## Constraints
2122

22-
<p>&nbsp;</p>
23-
<p><strong>Constraints:</strong></p>
24-
25-
<ul>
26-
<li><code>1 &lt;= s.length &lt;= 5 * 10<sup>4</sup></code></li>
27-
<li><code>0 &lt;= k &lt;= 50</code></li>
28-
</ul>
29-
30-
23+
- `1 <= s.length <= 5 * 10^4`
24+
- `0 <= k <= 50`
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,36 @@
1-
function lengthOfLongestSubstringKDistinct(s: string, k: number): number {
2-
if (k === 0) return 0;
1+
/**
2+
* @time - O(n) where n is the length of s
3+
* (each character visited at most twice by sliding window pointers)
4+
* @space - O(k) where k is the maximum number of distinct characters allowed;
5+
* the map stores at most k + 1 characters at any time before shrinking
6+
*/
7+
export function lengthOfLongestSubstringKDistinct(s: string, k: number): number {
8+
if (k === 0) return 0;
39

4-
const characterCount = new Map<string, number>();
5-
let left = 0;
6-
let maxLength = 0;
10+
const characterCount = new Map<string, number>();
11+
let left = 0;
12+
let maxLength = 0;
713

8-
for (let right = 0; right < s.length; right++) {
9-
const char = s[right];
10-
characterCount.set(char, (characterCount.get(char) || 0) + 1);
14+
// Expand the window by moving the right pointer
15+
for (let right = 0; right < s.length; right++) {
16+
const char = s[right];
17+
// Add current character to frequency map
18+
characterCount.set(char, (characterCount.get(char) || 0) + 1);
1119

12-
while (characterCount.size > k) {
13-
const leftChar = s[left];
14-
characterCount.set(leftChar, characterCount.get(leftChar)! - 1);
15-
if (characterCount.get(leftChar) === 0) {
16-
characterCount.delete(leftChar);
17-
}
18-
left++;
19-
}
20-
21-
maxLength = Math.max(maxLength, right - left + 1);
20+
// Shrink the window from the left if we have more than k distinct characters
21+
while (characterCount.size > k) {
22+
const leftChar = s[left];
23+
characterCount.set(leftChar, characterCount.get(leftChar)! - 1);
24+
// Remove the character from the map if its count drops to zero
25+
if (characterCount.get(leftChar) === 0) {
26+
characterCount.delete(leftChar);
27+
}
28+
left++;
2229
}
2330

24-
return maxLength;
25-
};
31+
// Update the maximum length found so far
32+
maxLength = Math.max(maxLength, right - left + 1);
33+
}
34+
35+
return maxLength;
36+
}

0 commit comments

Comments
 (0)