Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0caf311

Browse files
feat: update solutions to lc problems: No.0340~0342 (doocs#3288)
1 parent 6a59c00 commit 0caf311

File tree

18 files changed

+429
-606
lines changed

18 files changed

+429
-606
lines changed

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

Lines changed: 60 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,13 @@ tags:
5454

5555
### 方法一:滑动窗口 + 哈希表
5656

57-
我们可以使用滑动窗口的思想,维护一个滑动窗口,使得窗口内的字符串中不同字符的个数不超过 $k$ 个。窗口内不同字符个数的统计可以用哈希表 `cnt` 来维护
57+
我们可以使用滑动窗口的思想,用一个哈希表 $\textit{cnt}$ 记录窗口中每个字符的出现次数,用 $\textit{l}$ 记录窗口的左边界
5858

59-
我们使用两个指针 $j$ 和 $i$ 分别表示滑动窗口的左右边界。我们先移动右边界 $i,ドル将字符 $s[i]$ 加入到窗口内,扩大滑动窗口,若此时窗口内不同字符的个数超过 $k$ 个,则移动左边界 $j,ドル缩小滑动窗口,直到窗口内不同字符的个数不超过 $k$ 个。此时我们可以更新答案的最大值,即 $ans = max(ans, i - j + 1)$。
59+
遍历字符串,每次将右边界的字符加入哈希表,如果哈希表中不同字符的个数超过了 $k$,则将左边界的字符从哈希表中删除,然后更新左边界 $\textit{l}$。
6060

61-
时间复杂度 $O(n),ドル空间复杂度 $O(\min(n, k))$。其中 $n$ 为字符串的长度。
61+
最后返回字符串的长度减去左边界的长度即可。
62+
63+
时间复杂度 $O(n),ドル空间复杂度 $O(k)$。其中 $n$ 为字符串的长度。
6264

6365
<!-- tabs:start -->
6466

@@ -67,18 +69,16 @@ tags:
6769
```python
6870
class Solution:
6971
def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
72+
l = 0
7073
cnt = Counter()
71-
n = len(s)
72-
ans = j = 0
73-
for i, c in enumerate(s):
74+
for c in s:
7475
cnt[c] += 1
75-
while len(cnt) > k:
76-
cnt[s[j]] -= 1
77-
if cnt[s[j]] == 0:
78-
cnt.pop(s[j])
79-
j += 1
80-
ans = max(ans, i - j + 1)
81-
return ans
76+
if len(cnt) > k:
77+
cnt[s[l]] -= 1
78+
if cnt[s[l]] == 0:
79+
del cnt[s[l]]
80+
l += 1
81+
return len(s) - l
8282
```
8383

8484
#### Java
@@ -87,22 +87,18 @@ class Solution:
8787
class Solution {
8888
public int lengthOfLongestSubstringKDistinct(String s, int k) {
8989
Map<Character, Integer> cnt = new HashMap<>();
90-
int n = s.length();
91-
int ans = 0, j = 0;
92-
for (int i = 0; i < n; ++i) {
93-
char c = s.charAt(i);
94-
cnt.put(c, cnt.getOrDefault(c, 0) + 1);
95-
while (cnt.size() > k) {
96-
char t = s.charAt(j);
97-
cnt.put(t, cnt.getOrDefault(t, 0) - 1);
98-
if (cnt.get(t) == 0) {
99-
cnt.remove(t);
90+
int l = 0;
91+
char[] cs = s.toCharArray();
92+
for (char c : cs) {
93+
cnt.merge(c, 1, Integer::sum);
94+
if (cnt.size() > k) {
95+
if (cnt.merge(cs[l], -1, Integer::sum) == 0) {
96+
cnt.remove(cs[l]);
10097
}
101-
++j;
98+
++l;
10299
}
103-
ans = Math.max(ans, i - j + 1);
104100
}
105-
return ans;
101+
return cs.length - l;
106102
}
107103
}
108104
```
@@ -114,41 +110,58 @@ class Solution {
114110
public:
115111
int lengthOfLongestSubstringKDistinct(string s, int k) {
116112
unordered_map<char, int> cnt;
117-
int n = s.size();
118-
int ans = 0, j = 0;
119-
for (int i = 0; i < n; ++i) {
120-
cnt[s[i]]++;
121-
while (cnt.size() > k) {
122-
if (--cnt[s[j]] == 0) {
123-
cnt.erase(s[j]);
113+
int l = 0;
114+
for (char& c : s) {
115+
++cnt[c];
116+
if (cnt.size() > k) {
117+
if (--cnt[s[l]] == 0) {
118+
cnt.erase(s[l]);
124119
}
125-
++j;
120+
++l;
126121
}
127-
ans = max(ans, i - j + 1);
128122
}
129-
return ans;
123+
return s.size() - l;
130124
}
131125
};
132126
```
133127
134128
#### Go
135129
136130
```go
137-
func lengthOfLongestSubstringKDistinct(s string, k int) (ans int) {
131+
func lengthOfLongestSubstringKDistinct(s string, k int) int {
138132
cnt := map[byte]int{}
139-
j := 0
140-
for i := range s {
141-
cnt[s[i]]++
142-
for len(cnt) > k {
143-
cnt[s[j]]--
144-
if cnt[s[j]] == 0 {
145-
delete(cnt, s[j])
133+
l := 0
134+
for _, c := range s {
135+
cnt[byte(c)]++
136+
if len(cnt) > k {
137+
cnt[s[l]]--
138+
if cnt[s[l]] == 0 {
139+
delete(cnt, s[l])
146140
}
147-
j++
141+
l++
148142
}
149-
ans = max(ans, i-j+1)
150143
}
151-
return
144+
return len(s) - l
145+
}
146+
```
147+
148+
#### TypeScript
149+
150+
```ts
151+
function lengthOfLongestSubstringKDistinct(s: string, k: number): number {
152+
const cnt: Map<string, number> = new Map();
153+
let l = 0;
154+
for (const c of s) {
155+
cnt.set(c, (cnt.get(c) ?? 0) + 1);
156+
if (cnt.size > k) {
157+
cnt.set(s[l], cnt.get(s[l])! - 1);
158+
if (cnt.get(s[l]) === 0) {
159+
cnt.delete(s[l]);
160+
}
161+
l++;
162+
}
163+
}
164+
return s.length - l;
152165
}
153166
```
154167

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

Lines changed: 64 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,15 @@ tags:
5050

5151
<!-- solution:start -->
5252

53-
### Solution 1
53+
### Solution 1: Sliding Window + Hash Table
54+
55+
We can use the idea of a sliding window, with a hash table $\textit{cnt}$ to record the occurrence count of each character within the window, and $\textit{l}$ to denote the left boundary of the window.
56+
57+
Iterate through the string, adding the character at the right boundary to the hash table each time. If the number of distinct characters in the hash table exceeds $k,ドル remove the character at the left boundary from the hash table, then update the left boundary $\textit{l}$.
58+
59+
Finally, return the length of the string minus the length of the left boundary.
60+
61+
The time complexity is $O(n),ドル and the space complexity is $O(k)$. Here, $n$ is the length of the string.
5462

5563
<!-- tabs:start -->
5664

@@ -59,18 +67,16 @@ tags:
5967
```python
6068
class Solution:
6169
def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
70+
l = 0
6271
cnt = Counter()
63-
n = len(s)
64-
ans = j = 0
65-
for i, c in enumerate(s):
72+
for c in s:
6673
cnt[c] += 1
67-
while len(cnt) > k:
68-
cnt[s[j]] -= 1
69-
if cnt[s[j]] == 0:
70-
cnt.pop(s[j])
71-
j += 1
72-
ans = max(ans, i - j + 1)
73-
return ans
74+
if len(cnt) > k:
75+
cnt[s[l]] -= 1
76+
if cnt[s[l]] == 0:
77+
del cnt[s[l]]
78+
l += 1
79+
return len(s) - l
7480
```
7581

7682
#### Java
@@ -79,22 +85,18 @@ class Solution:
7985
class Solution {
8086
public int lengthOfLongestSubstringKDistinct(String s, int k) {
8187
Map<Character, Integer> cnt = new HashMap<>();
82-
int n = s.length();
83-
int ans = 0, j = 0;
84-
for (int i = 0; i < n; ++i) {
85-
char c = s.charAt(i);
86-
cnt.put(c, cnt.getOrDefault(c, 0) + 1);
87-
while (cnt.size() > k) {
88-
char t = s.charAt(j);
89-
cnt.put(t, cnt.getOrDefault(t, 0) - 1);
90-
if (cnt.get(t) == 0) {
91-
cnt.remove(t);
88+
int l = 0;
89+
char[] cs = s.toCharArray();
90+
for (char c : cs) {
91+
cnt.merge(c, 1, Integer::sum);
92+
if (cnt.size() > k) {
93+
if (cnt.merge(cs[l], -1, Integer::sum) == 0) {
94+
cnt.remove(cs[l]);
9295
}
93-
++j;
96+
++l;
9497
}
95-
ans = Math.max(ans, i - j + 1);
9698
}
97-
return ans;
99+
return cs.length - l;
98100
}
99101
}
100102
```
@@ -106,41 +108,58 @@ class Solution {
106108
public:
107109
int lengthOfLongestSubstringKDistinct(string s, int k) {
108110
unordered_map<char, int> cnt;
109-
int n = s.size();
110-
int ans = 0, j = 0;
111-
for (int i = 0; i < n; ++i) {
112-
cnt[s[i]]++;
113-
while (cnt.size() > k) {
114-
if (--cnt[s[j]] == 0) {
115-
cnt.erase(s[j]);
111+
int l = 0;
112+
for (char& c : s) {
113+
++cnt[c];
114+
if (cnt.size() > k) {
115+
if (--cnt[s[l]] == 0) {
116+
cnt.erase(s[l]);
116117
}
117-
++j;
118+
++l;
118119
}
119-
ans = max(ans, i - j + 1);
120120
}
121-
return ans;
121+
return s.size() - l;
122122
}
123123
};
124124
```
125125
126126
#### Go
127127
128128
```go
129-
func lengthOfLongestSubstringKDistinct(s string, k int) (ans int) {
129+
func lengthOfLongestSubstringKDistinct(s string, k int) int {
130130
cnt := map[byte]int{}
131-
j := 0
132-
for i := range s {
133-
cnt[s[i]]++
134-
for len(cnt) > k {
135-
cnt[s[j]]--
136-
if cnt[s[j]] == 0 {
137-
delete(cnt, s[j])
131+
l := 0
132+
for _, c := range s {
133+
cnt[byte(c)]++
134+
if len(cnt) > k {
135+
cnt[s[l]]--
136+
if cnt[s[l]] == 0 {
137+
delete(cnt, s[l])
138138
}
139-
j++
139+
l++
140140
}
141-
ans = max(ans, i-j+1)
142141
}
143-
return
142+
return len(s) - l
143+
}
144+
```
145+
146+
#### TypeScript
147+
148+
```ts
149+
function lengthOfLongestSubstringKDistinct(s: string, k: number): number {
150+
const cnt: Map<string, number> = new Map();
151+
let l = 0;
152+
for (const c of s) {
153+
cnt.set(c, (cnt.get(c) ?? 0) + 1);
154+
if (cnt.size > k) {
155+
cnt.set(s[l], cnt.get(s[l])! - 1);
156+
if (cnt.get(s[l]) === 0) {
157+
cnt.delete(s[l]);
158+
}
159+
l++;
160+
}
161+
}
162+
return s.length - l;
144163
}
145164
```
146165

‎solution/0300-0399/0340.Longest Substring with At Most K Distinct Characters/Solution.cpp‎

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@ class Solution {
22
public:
33
int lengthOfLongestSubstringKDistinct(string s, int k) {
44
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]);
5+
int l = 0;
6+
for (char& c : s) {
7+
++cnt[c];
8+
if (cnt.size() > k) {
9+
if (--cnt[s[l]] == 0) {
10+
cnt.erase(s[l]);
1211
}
13-
++j;
12+
++l;
1413
}
15-
ans = max(ans, i - j + 1);
1614
}
17-
return ans;
15+
return s.size() - l;
1816
}
1917
};
Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
func lengthOfLongestSubstringKDistinct(s string, k int) (ansint) {
1+
func lengthOfLongestSubstringKDistinct(s string, k int) int {
22
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])
3+
l := 0
4+
for _, c := range s {
5+
cnt[byte(c)]++
6+
if len(cnt) > k {
7+
cnt[s[l]]--
8+
if cnt[s[l]] == 0 {
9+
delete(cnt, s[l])
1010
}
11-
j++
11+
l++
1212
}
13-
ans = max(ans, i-j+1)
1413
}
15-
return
14+
returnlen(s) -l
1615
}
Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
class Solution {
22
public int lengthOfLongestSubstringKDistinct(String s, int k) {
33
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);
4+
int l = 0;
5+
char[] cs = s.toCharArray();
6+
for (char c : cs) {
7+
cnt.merge(c, 1, Integer::sum);
8+
if (cnt.size() > k) {
9+
if (cnt.merge(cs[l], -1, Integer::sum) == 0) {
10+
cnt.remove(cs[l]);
1411
}
15-
++j;
12+
++l;
1613
}
17-
ans = Math.max(ans, i - j + 1);
1814
}
19-
return ans;
15+
return cs.length - l;
2016
}
2117
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /