Skip to content

Commit 1bb1ac5

Browse files
committed
added 395
1 parent 0838fd2 commit 1bb1ac5

File tree

1 file changed

+332
-0
lines changed

1 file changed

+332
-0
lines changed
Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
---
2+
id: longest-substring-with-atleast-k-repeating-characters
3+
title: Longest Substring With Atleast K Repeating Characters
4+
sidebar_label: 0395-Longest Substring With Atleast K Repeating Characters
5+
tags:
6+
- Leet code
7+
description: "Solution to leetocde 395"
8+
---
9+
10+
### Problem Description
11+
12+
Given a string s and an integer k, return the length of the longest substring of s such that the frequency of each character in this substring is greater than or equal to k.
13+
14+
if no such substring exists, return 0.
15+
16+
### Examples
17+
18+
Example 1:
19+
20+
```
21+
Input: s = "aaabb", k = 3
22+
Output: 3
23+
Explanation: The longest substring is "aaa", as 'a' is repeated 3 times.
24+
```
25+
26+
Example 2:
27+
28+
```
29+
Input: s = "ababbc", k = 2
30+
Output: 5
31+
Explanation: The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.
32+
```
33+
34+
### Constraints:
35+
36+
- $1 <= s.length <= 10^4$
37+
- $s consists of only lowercase English letters.$
38+
- $1 <= k <= 10^5$
39+
40+
### Algorithm
41+
42+
1. **Initialize:**
43+
44+
- `ans`: stores the current maximum length of a valid substring
45+
- `freq`: frequency array to store character counts (size 26 for lowercase letters)
46+
- `n`: length of the string `s`
47+
48+
2. **Count Character Frequencies:**
49+
50+
- Iterate through `s` and update `freq[i]` for each character `s[i]`.
51+
52+
3. **Iterate Over Unique Character Counts:**
53+
54+
- Use a loop for `curr_unique` from 1 to the total number of unique characters (`unique`) found in step 2.
55+
56+
4. **Reset for Each Unique Character Count:**
57+
58+
- Reset `freq` array to 0 using `memset` (C/C++) or loop assignment (other languages).
59+
- Initialize `start`, `end`, `cnt` (number of unique characters in the window), and `count_k` (number of characters with at least `k` repetitions) to 0.
60+
61+
5. **Sliding Window Technique:**
62+
63+
- Use a `while` loop until `end` reaches the end of the string `s`:
64+
- **Expand Window:**
65+
- If `cnt` is less than `curr_unique`:
66+
- Increment `freq` for the character at `end`.
67+
- If the character is a new unique character (frequency becomes 1), increment `cnt`.
68+
- If the character's frequency becomes `k`, increment `count_k`.
69+
- Increment `end`.
70+
- **Shrink Window:**
71+
- If `cnt` is equal to `curr_unique`:
72+
- Decrement `freq` for the character at `start`.
73+
- If the character's frequency becomes `k-1`, decrement `count_k`.
74+
- If the character's frequency becomes 0, decrement `cnt`.
75+
- Increment `start`.
76+
77+
6. **Update Maximum Length:**
78+
79+
- If `cnt` is equal to `curr_unique` and `count_k` is also equal to `curr_unique` (all characters in the window have at least `k` repetitions), update `ans` with the maximum of the current length (`end - start`).
80+
81+
7. **Return Maximum Length:**
82+
- Return the final value of `ans`, which represents the length of the longest valid substring.
83+
84+
## Code Implementations:
85+
86+
**Python:**
87+
88+
```python
89+
def longestSubstring(s: str, k: int) -> int:
90+
ans = 0
91+
freq = [0] * 26
92+
93+
n = len(s)
94+
95+
for i in range(n):
96+
freq[ord(s[i]) - ord('a')] += 1
97+
98+
unique = sum(1 for count in freq if count > 0)
99+
100+
for curr_unique in range(1, unique + 1):
101+
memset(freq, 0, sizeof(freq)) # Replace with loop assignment for Python
102+
start = end = cnt = count_k = 0
103+
104+
while end < n:
105+
if cnt <= curr_unique:
106+
ind = ord(s[end]) - ord('a')
107+
if freq[ind] == 0:
108+
cnt += 1
109+
freq[ind] += 1
110+
if freq[ind] == k:
111+
count_k += 1
112+
end += 1
113+
else:
114+
ind = ord(s[start]) - ord('a')
115+
if freq[ind] == k:
116+
count_k -= 1
117+
freq[ind] -= 1
118+
if freq[ind] == 0:
119+
cnt -= 1
120+
start += 1
121+
122+
if cnt == curr_unique and count_k == curr_unique:
123+
ans = max(ans, end - start)
124+
125+
return ans
126+
```
127+
128+
**C++:**
129+
130+
```c++
131+
#include <vector>
132+
133+
int longestSubstring(std::string s, int k) {
134+
int ans = 0;
135+
std::vector<int> freq(26, 0);
136+
int n = s.size();
137+
138+
// Count character frequencies
139+
for (char c : s) {
140+
freq[c - 'a']++;
141+
}
142+
143+
// Find the number of unique characters
144+
int unique = 0;
145+
for (int count : freq) {
146+
if (count > 0) {
147+
unique++;
148+
}
149+
}
150+
151+
// Iterate over window sizes (1 to the number of unique characters)
152+
for (int curr_unique = 1; curr_unique <= unique; curr_unique++) {
153+
std::fill(freq.begin(), freq.end(), 0); // Reset frequencies for each window size
154+
155+
int start = 0, end = 0, cnt = 0, count_k = 0;
156+
157+
// Use a sliding window approach
158+
while (end < n) {
159+
if (cnt <= curr_unique) {
160+
int ind = s[end] - 'a';
161+
162+
// Expand window
163+
if (freq[ind] == 0) {
164+
cnt++;
165+
}
166+
freq[ind]++;
167+
if (freq[ind] == k) {
168+
count_k++;
169+
}
170+
end++;
171+
} else {
172+
int ind = s[start] - 'a';
173+
174+
// Shrink window
175+
if (freq[ind] == k) {
176+
count_k--;
177+
}
178+
freq[ind]--;
179+
if (freq[ind] == 0) {
180+
cnt--;
181+
}
182+
start++;
183+
}
184+
185+
// Check for valid window
186+
if (cnt == curr_unique && count_k == curr_unique) {
187+
ans = max(ans, end - start);
188+
}
189+
}
190+
}
191+
192+
return ans;
193+
}
194+
```
195+
196+
**Java:**
197+
198+
```java
199+
public class Solution {
200+
public int longestSubstring(String s, int k) {
201+
int ans = 0;
202+
int[] freq = new int[26];
203+
int n = s.length();
204+
205+
// Count character frequencies
206+
for (char c : s.toCharArray()) {
207+
freq[c - 'a']++;
208+
}
209+
210+
// Find the number of unique characters
211+
int unique = 0;
212+
for (int count : freq) {
213+
if (count > 0) {
214+
unique++;
215+
}
216+
}
217+
218+
// Iterate over window sizes (1 to the number of unique characters)
219+
for (int curr_unique = 1; curr_unique <= unique; curr_unique++) {
220+
Arrays.fill(freq, 0); // Reset frequencies for each window size
221+
222+
int start = 0, end = 0, cnt = 0, count_k = 0;
223+
224+
// Use a sliding window approach
225+
while (end < n) {
226+
if (cnt <= curr_unique) {
227+
int ind = s.charAt(end) - 'a';
228+
229+
// Expand window
230+
if (freq[ind] == 0) {
231+
cnt++;
232+
}
233+
freq[ind]++;
234+
if (freq[ind] == k) {
235+
count_k++;
236+
}
237+
end++;
238+
} else {
239+
int ind = s.charAt(start) - 'a';
240+
241+
// Shrink window
242+
if (freq[ind] == k) {
243+
count_k--;
244+
}
245+
freq[ind]--;
246+
if (freq[ind] == 0) {
247+
cnt--;
248+
}
249+
start++;
250+
}
251+
252+
// Check for valid window
253+
if (cnt == curr_unique && count_k == curr_unique) {
254+
ans = Math.max(ans, end - start);
255+
}
256+
}
257+
}
258+
259+
return ans;
260+
}
261+
}
262+
263+
```
264+
265+
**JavaScript:**
266+
267+
```javascript
268+
function longestSubstring(s, k) {
269+
let ans = 0;
270+
const freq = new Array(26).fill(0);
271+
const n = s.length;
272+
273+
// Count character frequencies
274+
for (const char of s) {
275+
freq[char.charCodeAt(0) - "a".charCodeAt(0)]++;
276+
}
277+
278+
// Find the number of unique characters
279+
let unique = 0;
280+
for (const count of freq) {
281+
if (count > 0) {
282+
unique++;
283+
}
284+
}
285+
286+
// Iterate over window sizes (1 to the number of unique characters)
287+
for (let curr_unique = 1; curr_unique <= unique; curr_unique++) {
288+
freq.fill(0); // Reset frequencies for each window size
289+
290+
let start = 0,
291+
end = 0,
292+
cnt = 0,
293+
count_k = 0;
294+
295+
// Use a sliding window approach
296+
while (end < n) {
297+
if (cnt <= curr_unique) {
298+
const ind = s.charCodeAt(end) - "a".charCodeAt(0);
299+
300+
// Expand window
301+
if (freq[ind] === 0) {
302+
cnt++;
303+
}
304+
freq[ind]++;
305+
if (freq[ind] === k) {
306+
count_k++;
307+
}
308+
end++;
309+
} else {
310+
const ind = s.charCodeAt(start) - "a".charCodeAt(0);
311+
312+
// Shrink window
313+
if (freq[ind] === k) {
314+
count_k--;
315+
}
316+
freq[ind]--;
317+
if (freq[ind] === 0) {
318+
cnt--;
319+
}
320+
start++;
321+
}
322+
323+
// Check for valid window
324+
if (cnt === curr_unique && count_k === curr_unique) {
325+
ans = Math.max(ans, end - start);
326+
}
327+
}
328+
}
329+
330+
return ans;
331+
}
332+
```

0 commit comments

Comments
 (0)