Skip to content

Commit 9668796

Browse files
committed
feat: add solutions to lc problem: No.0395
No.0395.Longest Substring with At Least K Repeating Characters
1 parent 6ab417e commit 9668796

File tree

6 files changed

+458
-216
lines changed

6 files changed

+458
-216
lines changed

solution/0300-0399/0395.Longest Substring with At Least K Repeating Characters/README.md

+160-72
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939

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

42+
**方法一:分治**
43+
44+
对于字符串 $s$,如果存在某个字符 $c$,其出现次数小于 $k$,则任何包含 $c$ 的子串都不可能满足题目要求。因此我们可以将 $s$ 按照每个不满足条件的字符 $c$ 进行分割,分割得到的每个子串都是原字符串的一个「子问题」,我们可以递归地求解每个子问题,最终的答案即为所有子问题的最大值。
45+
46+
时间复杂度 $O(n \times C)$,空间复杂度 $O(C^2)$。其中 $n$ 为字符串 $s$ 的长度,而 $C$ 为字符集的大小。本题中 $C \leq 26$。
47+
4248
<!-- tabs:start -->
4349

4450
### **Python3**
@@ -48,43 +54,27 @@
4854
```python
4955
class Solution:
5056
def longestSubstring(self, s: str, k: int) -> int:
51-
n = len(s)
52-
maxLength = 0
53-
54-
for i in range(1, 27):
55-
counter = dict()
56-
left = 0
57-
right = 0
58-
unique = 0
59-
kCount = 0
60-
61-
while right < n:
62-
if unique <= i:
63-
r = s[right]
64-
counter[r] = counter.get(r, 0) + 1
65-
66-
if counter[r] == 1:
67-
unique += 1
68-
if counter[r] == k:
69-
kCount += 1
70-
71-
right += 1
72-
73-
else:
74-
l = s[left]
75-
counter[l] = counter.get(l, 0) - 1
76-
77-
if counter[l] == 0:
78-
unique -= 1
79-
if counter[l] == k - 1:
80-
kCount -= 1
81-
82-
left += 1
83-
84-
if unique == i and kCount == i:
85-
maxLength = max(maxLength, right - left)
86-
87-
return maxLength
57+
def dfs(l, r):
58+
cnt = Counter(s[l: r + 1])
59+
split = next((c for c, v in cnt.items() if v < k), '')
60+
if not split:
61+
return r - l + 1
62+
i = l
63+
ans = 0
64+
while i <= r:
65+
while i <= r and s[i] == split:
66+
i += 1
67+
if i >= r:
68+
break
69+
j = i
70+
while j <= r and s[j] != split:
71+
j += 1
72+
t = dfs(i, j - 1)
73+
ans = max(ans, t)
74+
i = j
75+
return ans
76+
77+
return dfs(0, len(s) - 1)
8878
```
8979

9080
### **Java**
@@ -93,46 +83,144 @@ class Solution:
9383

9484
```java
9585
class Solution {
86+
private String s;
87+
private int k;
88+
9689
public int longestSubstring(String s, int k) {
97-
int maxLength = 0;
98-
int n = s.length();
99-
100-
for (int i = 1; i < 27; i++) {
101-
Map<Character, Integer> counter = new HashMap<>();
102-
int left = 0;
103-
int right = 0;
104-
int unique = 0;
105-
int kCount = 0;
106-
107-
while (right < n) {
108-
if (unique <= i) {
109-
char r = s.charAt(right);
110-
counter.put(r, counter.getOrDefault(r, 0) + 1);
111-
if (counter.get(r) == 1) {
112-
unique += 1;
113-
}
114-
if (counter.get(r) == k) {
115-
kCount += 1;
116-
}
117-
right += 1;
118-
} else {
119-
char l = s.charAt(left);
120-
counter.put(l, counter.getOrDefault(l, 2) - 1);
121-
if (counter.get(l) == 0) {
122-
unique -= 1;
123-
}
124-
if (counter.get(l) == k - 1) {
125-
kCount -= 1;
126-
}
127-
left += 1;
90+
this.s = s;
91+
this.k = k;
92+
return dfs(0, s.length() - 1);
93+
}
94+
95+
private int dfs(int l, int r) {
96+
int[] cnt = new int[26];
97+
for (int i = l; i <= r; ++i) {
98+
++cnt[s.charAt(i) - 'a'];
99+
}
100+
char split = 0;
101+
for (int i = 0; i < 26; ++i) {
102+
if (cnt[i] > 0 && cnt[i] < k) {
103+
split = (char) (i + 'a');
104+
break;
105+
}
106+
}
107+
if (split == 0) {
108+
return r - l + 1;
109+
}
110+
int i = l;
111+
int ans = 0;
112+
while (i <= r) {
113+
while (i <= r && s.charAt(i) == split) {
114+
++i;
115+
}
116+
if (i > r) {
117+
break;
118+
}
119+
int j = i;
120+
while (j <= r && s.charAt(j) != split) {
121+
++j;
122+
}
123+
int t = dfs(i, j - 1);
124+
ans = Math.max(ans, t);
125+
i = j;
126+
}
127+
return ans;
128+
}
129+
}
130+
```
131+
132+
### **C++**
133+
134+
```cpp
135+
class Solution {
136+
public:
137+
int longestSubstring(string s, int k) {
138+
function<int(int, int)> dfs = [&](int l, int r) -> int {
139+
int cnt[26] = {0};
140+
for (int i = l; i <= r; ++i) {
141+
cnt[s[i] - 'a']++;
142+
}
143+
char split = 0;
144+
for (int i = 0; i < 26; ++i) {
145+
if (cnt[i] > 0 && cnt[i] < k) {
146+
split = 'a' + i;
147+
break;
128148
}
129-
if (unique == i && kCount == i) {
130-
maxLength = Math.max(maxLength, right - left);
149+
}
150+
if (split == 0) {
151+
return r - l + 1;
152+
}
153+
int i = l;
154+
int ans = 0;
155+
while (i <= r) {
156+
while (i <= r && s[i] == split) {
157+
++i;
158+
}
159+
if (i >= r) {
160+
break;
131161
}
162+
int j = i;
163+
while (j <= r && s[j] != split) {
164+
++j;
165+
}
166+
int t = dfs(i, j - 1);
167+
ans = max(ans, t);
168+
i = j;
132169
}
133-
}
134-
return maxLength;
170+
return ans;
171+
};
172+
return dfs(0, s.size() - 1);
135173
}
174+
};
175+
```
176+
177+
### **Go**
178+
179+
```go
180+
func longestSubstring(s string, k int) int {
181+
var dfs func(l, r int) int
182+
dfs = func(l, r int) int {
183+
cnt := [26]int{}
184+
for i := l; i <= r; i++ {
185+
cnt[s[i]-'a']++
186+
}
187+
var split byte
188+
for i, v := range cnt {
189+
if v > 0 && v < k {
190+
split = byte(i + 'a')
191+
break
192+
}
193+
}
194+
if split == 0 {
195+
return r - l + 1
196+
}
197+
i := l
198+
ans := 0
199+
for i <= r {
200+
for i <= r && s[i] == split {
201+
i++
202+
}
203+
if i > r {
204+
break
205+
}
206+
j := i
207+
for j <= r && s[j] != split {
208+
j++
209+
}
210+
t := dfs(i, j-1)
211+
ans = max(ans, t)
212+
i = j
213+
}
214+
return ans
215+
}
216+
return dfs(0, len(s)-1)
217+
}
218+
219+
func max(a, b int) int {
220+
if a > b {
221+
return a
222+
}
223+
return b
136224
}
137225
```
138226

0 commit comments

Comments
 (0)