39
39
40
40
<!-- 这里可写通用的实现逻辑 -->
41
41
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
+
42
48
<!-- tabs:start -->
43
49
44
50
### ** Python3**
48
54
``` python
49
55
class Solution :
50
56
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 )
88
78
```
89
79
90
80
### ** Java**
@@ -93,46 +83,144 @@ class Solution:
93
83
94
84
``` java
95
85
class Solution {
86
+ private String s;
87
+ private int k;
88
+
96
89
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;
128
148
}
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;
131
161
}
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;
132
169
}
133
- }
134
- return maxLength;
170
+ return ans;
171
+ };
172
+ return dfs(0, s.size() - 1);
135
173
}
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
136
224
}
137
225
```
138
226
0 commit comments