Skip to content

Commit 6ab417e

Browse files
committed
feat: add solutions to lc problem: No.0340
No.0340.Longest Substring with At Most K Distinct Characters
1 parent 507a952 commit 6ab417e

File tree

6 files changed

+257
-2
lines changed

6 files changed

+257
-2
lines changed

solution/0300-0399/0340.Longest Substring with At Most K Distinct Characters/README.md

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,115 @@
3838

3939
<!-- 这里可写通用的实现逻辑 -->
4040

41+
**方法一:滑动窗口 + 哈希表**
42+
43+
我们可以使用滑动窗口的思想,维护一个滑动窗口,使得窗口内的字符串中不同字符的个数不超过 $k$ 个。窗口内不同字符个数的统计可以用哈希表 `cnt` 来维护。
44+
45+
我们使用两个指针 $j$ 和 $i$ 分别表示滑动窗口的左右边界。我们先移动右边界 $i$,将字符 $s[i]$ 加入到窗口内,扩大滑动窗口,若此时窗口内不同字符的个数超过 $k$ 个,则移动左边界 $j$,缩小滑动窗口,直到窗口内不同字符的个数不超过 $k$ 个。此时我们可以更新答案的最大值,即 $ans = max(ans, i - j + 1)$。
46+
47+
时间复杂度 $O(n)$,空间复杂度 $O(\min(n, k))$。其中 $n$ 为字符串的长度。
48+
4149
<!-- tabs:start -->
4250

4351
### **Python3**
4452

4553
<!-- 这里可写当前语言的特殊实现逻辑 -->
4654

4755
```python
48-
56+
class Solution:
57+
def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
58+
cnt = Counter()
59+
n = len(s)
60+
ans = j = 0
61+
for i, c in enumerate(s):
62+
cnt[c] += 1
63+
while len(cnt) > k:
64+
cnt[s[j]] -= 1
65+
if cnt[s[j]] == 0:
66+
cnt.pop(s[j])
67+
j += 1
68+
ans = max(ans, i - j + 1)
69+
return ans
4970
```
5071

5172
### **Java**
5273

5374
<!-- 这里可写当前语言的特殊实现逻辑 -->
5475

5576
```java
77+
class Solution {
78+
public int lengthOfLongestSubstringKDistinct(String s, int k) {
79+
Map<Character, Integer> cnt = new HashMap<>();
80+
int n = s.length();
81+
int ans = 0, j = 0;
82+
for (int i = 0; i < n; ++i) {
83+
char c = s.charAt(i);
84+
cnt.put(c, cnt.getOrDefault(c, 0) + 1);
85+
while (cnt.size() > k) {
86+
char t = s.charAt(j);
87+
cnt.put(t, cnt.getOrDefault(t, 0) - 1);
88+
if (cnt.get(t) == 0) {
89+
cnt.remove(t);
90+
}
91+
++j;
92+
}
93+
ans = Math.max(ans, i - j + 1);
94+
}
95+
return ans;
96+
}
97+
}
98+
```
99+
100+
### **C++**
101+
102+
```cpp
103+
class Solution {
104+
public:
105+
int lengthOfLongestSubstringKDistinct(string s, int k) {
106+
unordered_map<char, int> cnt;
107+
int n = s.size();
108+
int ans = 0, j = 0;
109+
for (int i = 0; i < n; ++i) {
110+
cnt[s[i]]++;
111+
while (cnt.size() > k) {
112+
if (--cnt[s[j]] == 0) {
113+
cnt.erase(s[j]);
114+
}
115+
++j;
116+
}
117+
ans = max(ans, i - j + 1);
118+
}
119+
return ans;
120+
}
121+
};
122+
```
56123
124+
### **Go**
125+
126+
```go
127+
func lengthOfLongestSubstringKDistinct(s string, k int) (ans int) {
128+
cnt := map[byte]int{}
129+
j := 0
130+
for i := range s {
131+
cnt[s[i]]++
132+
for len(cnt) > k {
133+
cnt[s[j]]--
134+
if cnt[s[j]] == 0 {
135+
delete(cnt, s[j])
136+
}
137+
j++
138+
}
139+
ans = max(ans, i-j+1)
140+
}
141+
return
142+
}
143+
144+
func max(a, b int) int {
145+
if a > b {
146+
return a
147+
}
148+
return b
149+
}
57150
```
58151

59152
### **...**

solution/0300-0399/0340.Longest Substring with At Most K Distinct Characters/README_EN.md

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,98 @@
3737
### **Python3**
3838

3939
```python
40-
40+
class Solution:
41+
def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
42+
cnt = Counter()
43+
n = len(s)
44+
ans = j = 0
45+
for i, c in enumerate(s):
46+
cnt[c] += 1
47+
while len(cnt) > k:
48+
cnt[s[j]] -= 1
49+
if cnt[s[j]] == 0:
50+
cnt.pop(s[j])
51+
j += 1
52+
ans = max(ans, i - j + 1)
53+
return ans
4154
```
4255

4356
### **Java**
4457

4558
```java
59+
class Solution {
60+
public int lengthOfLongestSubstringKDistinct(String s, int k) {
61+
Map<Character, Integer> cnt = new HashMap<>();
62+
int n = s.length();
63+
int ans = 0, j = 0;
64+
for (int i = 0; i < n; ++i) {
65+
char c = s.charAt(i);
66+
cnt.put(c, cnt.getOrDefault(c, 0) + 1);
67+
while (cnt.size() > k) {
68+
char t = s.charAt(j);
69+
cnt.put(t, cnt.getOrDefault(t, 0) - 1);
70+
if (cnt.get(t) == 0) {
71+
cnt.remove(t);
72+
}
73+
++j;
74+
}
75+
ans = Math.max(ans, i - j + 1);
76+
}
77+
return ans;
78+
}
79+
}
80+
```
81+
82+
### **C++**
83+
84+
```cpp
85+
class Solution {
86+
public:
87+
int lengthOfLongestSubstringKDistinct(string s, int k) {
88+
unordered_map<char, int> cnt;
89+
int n = s.size();
90+
int ans = 0, j = 0;
91+
for (int i = 0; i < n; ++i) {
92+
cnt[s[i]]++;
93+
while (cnt.size() > k) {
94+
if (--cnt[s[j]] == 0) {
95+
cnt.erase(s[j]);
96+
}
97+
++j;
98+
}
99+
ans = max(ans, i - j + 1);
100+
}
101+
return ans;
102+
}
103+
};
104+
```
46105
106+
### **Go**
107+
108+
```go
109+
func lengthOfLongestSubstringKDistinct(s string, k int) (ans int) {
110+
cnt := map[byte]int{}
111+
j := 0
112+
for i := range s {
113+
cnt[s[i]]++
114+
for len(cnt) > k {
115+
cnt[s[j]]--
116+
if cnt[s[j]] == 0 {
117+
delete(cnt, s[j])
118+
}
119+
j++
120+
}
121+
ans = max(ans, i-j+1)
122+
}
123+
return
124+
}
125+
126+
func max(a, b int) int {
127+
if a > b {
128+
return a
129+
}
130+
return b
131+
}
47132
```
48133

49134
### **...**
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Solution {
2+
public:
3+
int lengthOfLongestSubstringKDistinct(string s, int k) {
4+
unordered_map<char, int> cnt;
5+
int n = s.size();
6+
int ans = 0, j = 0;
7+
for (int i = 0; i < n; ++i) {
8+
cnt[s[i]]++;
9+
while (cnt.size() > k) {
10+
if (--cnt[s[j]] == 0) {
11+
cnt.erase(s[j]);
12+
}
13+
++j;
14+
}
15+
ans = max(ans, i - j + 1);
16+
}
17+
return ans;
18+
}
19+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
func lengthOfLongestSubstringKDistinct(s string, k int) (ans int) {
2+
cnt := map[byte]int{}
3+
j := 0
4+
for i := range s {
5+
cnt[s[i]]++
6+
for len(cnt) > k {
7+
cnt[s[j]]--
8+
if cnt[s[j]] == 0 {
9+
delete(cnt, s[j])
10+
}
11+
j++
12+
}
13+
ans = max(ans, i-j+1)
14+
}
15+
return
16+
}
17+
18+
func max(a, b int) int {
19+
if a > b {
20+
return a
21+
}
22+
return b
23+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution {
2+
public int lengthOfLongestSubstringKDistinct(String s, int k) {
3+
Map<Character, Integer> cnt = new HashMap<>();
4+
int n = s.length();
5+
int ans = 0, j = 0;
6+
for (int i = 0; i < n; ++i) {
7+
char c = s.charAt(i);
8+
cnt.put(c, cnt.getOrDefault(c, 0) + 1);
9+
while (cnt.size() > k) {
10+
char t = s.charAt(j);
11+
cnt.put(t, cnt.getOrDefault(t, 0) - 1);
12+
if (cnt.get(t) == 0) {
13+
cnt.remove(t);
14+
}
15+
++j;
16+
}
17+
ans = Math.max(ans, i - j + 1);
18+
}
19+
return ans;
20+
}
21+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Solution:
2+
def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
3+
cnt = Counter()
4+
n = len(s)
5+
ans = j = 0
6+
for i, c in enumerate(s):
7+
cnt[c] += 1
8+
while len(cnt) > k:
9+
cnt[s[j]] -= 1
10+
if cnt[s[j]] == 0:
11+
cnt.pop(s[j])
12+
j += 1
13+
ans = max(ans, i - j + 1)
14+
return ans

0 commit comments

Comments
 (0)