@@ -222,6 +222,41 @@ func abs(x int) int {
222
222
}
223
223
```
224
224
225
+ #### TypeScript
226
+
227
+ ``` ts
228
+ function equalSubstring(s : string , t : string , maxCost : number ): number {
229
+ const n = s .length ;
230
+ const f = Array (n + 1 ).fill (0 );
231
+
232
+ for (let i = 0 ; i < n ; i ++ ) {
233
+ f [i + 1 ] = f [i ] + Math .abs (s .charCodeAt (i ) - t .charCodeAt (i ));
234
+ }
235
+
236
+ const check = (x : number ): boolean => {
237
+ for (let i = 0 ; i + x - 1 < n ; i ++ ) {
238
+ if (f [i + x ] - f [i ] <= maxCost ) {
239
+ return true ;
240
+ }
241
+ }
242
+ return false ;
243
+ };
244
+
245
+ let l = 0 ,
246
+ r = n ;
247
+ while (l < r ) {
248
+ const mid = (l + r + 1 ) >> 1 ;
249
+ if (check (mid )) {
250
+ l = mid ;
251
+ } else {
252
+ r = mid - 1 ;
253
+ }
254
+ }
255
+
256
+ return l ;
257
+ }
258
+ ```
259
+
225
260
<!-- tabs: end -->
226
261
227
262
<!-- solution: end -->
@@ -230,11 +265,11 @@ func abs(x int) int {
230
265
231
266
### 方法二:双指针
232
267
233
- 我们可以维护两个指针 $j $ 和 $i $,初始时 $i = j = 0$;维护一个变量 $sum $,表示下标区间 $[ i ,..j ] $ 之间的 ASCII 码值的差的绝对值之和。在每一步中,我们将 $i $ 向右移动一位,然后更新 $sum = sum + |s[ i ] - t[ i ] |$。如果 $sum \gt maxCost$,那么我们就循环将指针 $j$ 向右移动,并且在移动过程中不断减少 $sum $ 的值,直到 $sum \leq maxCost$。然后我们更新答案,即 $ans = \max(ans, i - j + 1)$。
268
+ 我们可以维护两个指针 $l $ 和 $r $,初始时 $l = r = 0$;维护一个变量 $\text{cost} $,表示下标区间 $[ l ,..r ] $ 之间的 ASCII 码值的差的绝对值之和。在每一步中,我们将 $r $ 向右移动一位,然后更新 $\text{cost} = \text{cost} + |s[ r ] - t[ r ] |$。如果 $\text{cost} \gt \text{ maxCost}$,那么我们就循环将 $l$ 向右移动一位,并且减少 $\text{cost} $ 的值,直到 $\text{cost} \leq \text{ maxCost} $。然后我们更新答案,即 $\text{ ans} = \max(\text{ ans}, r - l + 1)$。
234
269
235
270
最后返回答案即可。
236
271
237
- 时间复杂度 $O(n)$,空间复杂度 $O(1)$。 其中 $n$ 为字符串 $s$ 的长度。
272
+ 时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。空间复杂度 $O(1)$ 。
238
273
239
274
<!-- tabs: start -->
240
275
@@ -244,14 +279,13 @@ func abs(x int) int {
244
279
class Solution :
245
280
def equalSubstring (self , s : str , t : str , maxCost : int ) -> int :
246
281
n = len (s)
247
- sum = j = 0
248
- ans = 0
249
- for i in range (n):
250
- sum += abs (ord (s[i]) - ord (t[i]))
251
- while sum > maxCost:
252
- sum -= abs (ord (s[j]) - ord (t[j]))
253
- j += 1
254
- ans = max (ans, i - j + 1 )
282
+ ans = cost = l = 0
283
+ for r in range (n):
284
+ cost += abs (ord (s[r]) - ord (t[r]))
285
+ while cost > maxCost:
286
+ cost -= abs (ord (s[l]) - ord (t[l]))
287
+ l += 1
288
+ ans = max (ans, r - l + 1 )
255
289
return ans
256
290
```
257
291
@@ -261,15 +295,14 @@ class Solution:
261
295
class Solution {
262
296
public int equalSubstring (String s , String t , int maxCost ) {
263
297
int n = s. length();
264
- int sum = 0 ;
265
- int ans = 0 ;
266
- for (int i = 0 , j = 0 ; i < n; ++ i) {
267
- sum += Math . abs(s. charAt(i) - t. charAt(i));
268
- while (sum > maxCost) {
269
- sum -= Math . abs(s. charAt(j) - t. charAt(j));
270
- ++ j;
298
+ int ans = 0 , cost = 0 ;
299
+ for (int l = 0 , r = 0 ; r < n; ++ r) {
300
+ cost += Math . abs(s. charAt(r) - t. charAt(r));
301
+ while (cost > maxCost) {
302
+ cost -= Math . abs(s. charAt(l) - t. charAt(l));
303
+ ++ l;
271
304
}
272
- ans = Math . max(ans, i - j + 1 );
305
+ ans = Math . max(ans, r - l + 1 );
273
306
}
274
307
return ans;
275
308
}
@@ -282,15 +315,15 @@ class Solution {
282
315
class Solution {
283
316
public:
284
317
int equalSubstring(string s, string t, int maxCost) {
285
- int n = s.size ();
286
- int ans = 0, sum = 0;
287
- for (int i = 0, j = 0; i < n; ++i ) {
288
- sum += abs(s[ i ] - t[ i ] );
289
- while (sum > maxCost) {
290
- sum -= abs(s[ j ] - t[ j ] );
291
- ++j ;
318
+ int n = s.length ();
319
+ int ans = 0, cost = 0;
320
+ for (int l = 0, r = 0; r < n; ++r ) {
321
+ cost += abs(s[ r ] - t[ r ] );
322
+ while (cost > maxCost) {
323
+ cost -= abs(s[ l ] - t[ l ] );
324
+ ++l ;
292
325
}
293
- ans = max(ans, i - j + 1);
326
+ ans = max(ans, r - l + 1);
294
327
}
295
328
return ans;
296
329
}
@@ -301,15 +334,13 @@ public:
301
334
302
335
```go
303
336
func equalSubstring(s string, t string, maxCost int) (ans int) {
304
- var sum, j int
305
- for i := range s {
306
- sum += abs(int(s[i]) - int(t[i]))
307
- for ; sum > maxCost; j++ {
308
- sum -= abs(int(s[j]) - int(t[j]))
309
- }
310
- if ans < i-j+1 {
311
- ans = i - j + 1
337
+ var cost, l int
338
+ for r := range s {
339
+ cost += abs(int(s[r]) - int(t[r]))
340
+ for ; cost > maxCost; l++ {
341
+ cost -= abs(int(s[l]) - int(t[l]))
312
342
}
343
+ ans = max(ans, r-l+1)
313
344
}
314
345
return
315
346
}
@@ -322,6 +353,138 @@ func abs(x int) int {
322
353
}
323
354
```
324
355
356
+ #### TypeScript
357
+
358
+ ``` ts
359
+ function equalSubstring(s : string , t : string , maxCost : number ): number {
360
+ const getCost = (i : number ) => Math .abs (s [i ].charCodeAt (0 ) - t [i ].charCodeAt (0 ));
361
+ const n = s .length ;
362
+ let ans = 0 ,
363
+ cost = 0 ;
364
+ for (let l = 0 , r = 0 ; r < n ; ++ r ) {
365
+ cost += getCost (r );
366
+ while (cost > maxCost ) {
367
+ cost -= getCost (l ++ );
368
+ }
369
+ ans = Math .max (ans , r - l + 1 );
370
+ }
371
+ return ans ;
372
+ }
373
+ ```
374
+
375
+ <!-- tabs: end -->
376
+
377
+ <!-- solution: end -->
378
+
379
+ <!-- solution: start -->
380
+
381
+ ### 方法三:双指针的另一种写法
382
+
383
+ 在方法二中,双指针维护的区间可能变短,也可能变长,由于题目只需要求出最大长度,我们可以维护一个单调变长的区间。
384
+
385
+ 具体地,我们用两个指针 $l$ 和 $r$ 指向区间的左右端点,初始时 $l = r = 0$。在每一步中,我们将 $r$ 向右移动一位,然后更新 $\text{cost} = \text{cost} + |s[ r] - t[ r] |$。如果 $\text{cost} \gt \text{maxCost}$,那么我们就将 $l$ 向右移动一位,并且减少 $\text{cost}$ 的值。
386
+
387
+ 最后返回 $n - l$ 即可。
388
+
389
+ 时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。空间复杂度 $O(1)$。
390
+
391
+ <!-- tabs: start -->
392
+
393
+ #### Python3
394
+
395
+ ``` python
396
+ class Solution :
397
+ def equalSubstring (self , s : str , t : str , maxCost : int ) -> int :
398
+ cost = l = 0
399
+ for a, b in zip (s, t):
400
+ cost += abs (ord (a) - ord (b))
401
+ if cost > maxCost:
402
+ cost -= abs (ord (s[l]) - ord (t[l]))
403
+ l += 1
404
+ return len (s) - l
405
+ ```
406
+
407
+ #### Java
408
+
409
+ ``` java
410
+ class Solution {
411
+ public int equalSubstring (String s , String t , int maxCost ) {
412
+ int n = s. length();
413
+ int cost = 0 , l = 0 ;
414
+ for (int r = 0 ; r < n; ++ r) {
415
+ cost += Math . abs(s. charAt(r) - t. charAt(r));
416
+ if (cost > maxCost) {
417
+ cost -= Math . abs(s. charAt(l) - t. charAt(l));
418
+ ++ l;
419
+ }
420
+ }
421
+ return n - l;
422
+ }
423
+ }
424
+ ```
425
+
426
+ #### C++
427
+
428
+ ``` cpp
429
+ class Solution {
430
+ public:
431
+ int equalSubstring(string s, string t, int maxCost) {
432
+ int n = s.length();
433
+ int cost = 0, l = 0;
434
+ for (int r = 0; r < n; ++r) {
435
+ cost += abs(s[ r] - t[ r] );
436
+ if (cost > maxCost) {
437
+ cost -= abs(s[ l] - t[ l] );
438
+ ++l;
439
+ }
440
+ }
441
+ return n - l;
442
+ }
443
+ };
444
+ ```
445
+
446
+ #### Go
447
+
448
+ ```go
449
+ func equalSubstring(s string, t string, maxCost int) int {
450
+ n := len(s)
451
+ var cost, l int
452
+ for r := range s {
453
+ cost += abs(int(s[r]) - int(t[r]))
454
+ if cost > maxCost {
455
+ cost -= abs(int(s[l]) - int(t[l]))
456
+ l++
457
+ }
458
+ }
459
+ return n - l
460
+ }
461
+
462
+ func abs(x int) int {
463
+ if x < 0 {
464
+ return -x
465
+ }
466
+ return x
467
+ }
468
+ ```
469
+
470
+ #### TypeScript
471
+
472
+ ``` ts
473
+ function equalSubstring(s : string , t : string , maxCost : number ): number {
474
+ const getCost = (i : number ) => Math .abs (s [i ].charCodeAt (0 ) - t [i ].charCodeAt (0 ));
475
+ const n = s .length ;
476
+ let cost = 0 ;
477
+ let l = 0 ;
478
+ for (let r = 0 ; r < n ; ++ r ) {
479
+ cost += getCost (r );
480
+ if (cost > maxCost ) {
481
+ cost -= getCost (l ++ );
482
+ }
483
+ }
484
+ return n - l ;
485
+ }
486
+ ```
487
+
325
488
<!-- tabs: end -->
326
489
327
490
<!-- solution: end -->
0 commit comments