@@ -244,32 +244,343 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3777.Mi
244244
245245<!-- solution:start -->
246246
247- ### 方法一
247+ ### 方法一:树状数组
248+
249+ 我们可以将字符串 $s$ 转换为一个长度为 $n$ 的数组 $\textit{nums}$,其中 $\textit{nums}[ 0] = 0$,对于 $1 \leq i < n$,如果 $s[ i] = s[ i-1] $,则 $\textit{nums}[ i] = 1$,否则 $\textit{nums}[ i] = 0$。这样 $\textit{nums}[ i] $ 表示在索引 $i$ 处是否存在相邻且相等的字符。那么我们计算区间 $[ l, r] $ 内使子字符串 $s[ l..r] $ 变成交替字符串所需的最小字符删除数就等价于计算 $\textit{nums}$ 数组在区间 $[ l+1, r] $ 上的元素和。
250+
251+ 为了高效地处理查询,我们可以使用树状数组来维护 $\textit{nums}$ 数组的前缀和。对于类型为 $[ 1, j] $ 的查询,我们需要将 $\textit{nums}[ j] $ 和 $\textit{nums}[ j+1] $(如果 $j+1 < n$)进行翻转,并更新树状数组。对于类型为 $[ 2, l, r] $ 的查询,我们可以通过树状数组快速计算区间 $[ l+1, r] $ 上的元素和。
252+
253+ 时间复杂度 $O((n + q) \log n)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度,而 $q$ 是查询的数量。
248254
249255<!-- tabs:start -->
250256
251257#### Python3
252258
253259``` python
254-
260+ class BinaryIndexedTree :
261+ __slots__ = " n" , " c"
262+
263+ def __init__ (self , n : int ):
264+ self .n = n
265+ self .c = [0 ] * (n + 1 )
266+
267+ def update (self , x : int , delta : int ) -> None :
268+ while x <= self .n:
269+ self .c[x] += delta
270+ x += x & - x
271+
272+ def query (self , x : int ) -> int :
273+ s = 0
274+ while x:
275+ s += self .c[x]
276+ x -= x & - x
277+ return s
278+
279+
280+ class Solution :
281+ def minDeletions (self , s : str , queries : List[List[int ]]) -> List[int ]:
282+ n = len (s)
283+ nums = [0 ] * n
284+ bit = BinaryIndexedTree(n)
285+ for i in range (1 , n):
286+ nums[i] = int (s[i] == s[i - 1 ])
287+ if nums[i]:
288+ bit.update(i + 1 , 1 )
289+ ans = []
290+ for q in queries:
291+ if q[0 ] == 1 :
292+ j = q[1 ]
293+ delta = (nums[j] ^ 1 ) - nums[j]
294+ nums[j] ^= 1
295+ bit.update(j + 1 , delta)
296+ if j + 1 < n:
297+ delta = (nums[j + 1 ] ^ 1 ) - nums[j + 1 ]
298+ nums[j + 1 ] ^= 1
299+ bit.update(j + 2 , delta)
300+ else :
301+ _, l, r = q
302+ ans.append(bit.query(r + 1 ) - bit.query(l + 1 ))
303+ return ans
255304```
256305
257306#### Java
258307
259308``` java
260-
309+ class BinaryIndexedTree {
310+ int n;
311+ int [] c;
312+
313+ BinaryIndexedTree (int n ) {
314+ this . n = n;
315+ this . c = new int [n + 1 ];
316+ }
317+
318+ void update (int x , int delta ) {
319+ while (x <= n) {
320+ c[x] += delta;
321+ x += x & - x;
322+ }
323+ }
324+
325+ int query (int x ) {
326+ int s = 0 ;
327+ while (x > 0 ) {
328+ s += c[x];
329+ x -= x & - x;
330+ }
331+ return s;
332+ }
333+ }
334+
335+ class Solution {
336+ public int [] minDeletions (String s , int [][] queries ) {
337+ int n = s. length();
338+ int [] nums = new int [n];
339+ BinaryIndexedTree bit = new BinaryIndexedTree (n);
340+
341+ for (int i = 1 ; i < n; i++ ) {
342+ nums[i] = (s. charAt(i) == s. charAt(i - 1 )) ? 1 : 0 ;
343+ if (nums[i] == 1 ) {
344+ bit. update(i + 1 , 1 );
345+ }
346+ }
347+
348+ int cnt = 0 ;
349+ for (int [] q : queries) {
350+ if (q[0 ] == 2 ) {
351+ cnt++ ;
352+ }
353+ }
354+
355+ int [] ans = new int [cnt];
356+ int idx = 0 ;
357+
358+ for (int [] q : queries) {
359+ if (q[0 ] == 1 ) {
360+ int j = q[1 ];
361+
362+ int delta = (nums[j] ^ 1 ) - nums[j];
363+ nums[j] ^ = 1 ;
364+ bit. update(j + 1 , delta);
365+
366+ if (j + 1 < n) {
367+ delta = (nums[j + 1 ] ^ 1 ) - nums[j + 1 ];
368+ nums[j + 1 ] ^ = 1 ;
369+ bit. update(j + 2 , delta);
370+ }
371+ } else {
372+ int l = q[1 ];
373+ int r = q[2 ];
374+ ans[idx++ ] = bit. query(r + 1 ) - bit. query(l + 1 );
375+ }
376+ }
377+ return ans;
378+ }
379+ }
261380```
262381
263382#### C++
264383
265384``` cpp
266-
385+ class BinaryIndexedTree {
386+ public:
387+ int n;
388+ vector<int > c;
389+
390+ BinaryIndexedTree(int n)
391+ : n(n)
392+ , c(n + 1, 0) {}
393+
394+ void update (int x, int delta) {
395+ while (x <= n) {
396+ c[ x] += delta;
397+ x += x & -x;
398+ }
399+ }
400+
401+ int query(int x) {
402+ int s = 0;
403+ while (x > 0) {
404+ s += c[x];
405+ x -= x & -x;
406+ }
407+ return s;
408+ }
409+ };
410+
411+ class Solution {
412+ public:
413+ vector<int > minDeletions(string s, vector<vector<int >>& queries) {
414+ int n = s.size();
415+ vector<int > nums(n, 0);
416+ BinaryIndexedTree bit(n);
417+
418+ for (int i = 1; i < n; i++) {
419+ nums[i] = (s[i] == s[i - 1]);
420+ if (nums[i]) {
421+ bit.update(i + 1, 1);
422+ }
423+ }
424+
425+ vector<int> ans;
426+
427+ for (auto& q : queries) {
428+ if (q[0] == 1) {
429+ int j = q[1];
430+
431+ int delta = (nums[j] ^ 1) - nums[j];
432+ nums[j] ^= 1;
433+ bit.update(j + 1, delta);
434+
435+ if (j + 1 < n) {
436+ delta = (nums[j + 1] ^ 1) - nums[j + 1];
437+ nums[j + 1] ^= 1;
438+ bit.update(j + 2, delta);
439+ }
440+ } else {
441+ int l = q[1];
442+ int r = q[2];
443+ ans.push_back(bit.query(r + 1) - bit.query(l + 1));
444+ }
445+ }
446+ return ans;
447+ }
448+ };
267449```
268450
269451#### Go
270452
271453```go
454+ type binaryIndexedTree struct {
455+ n int
456+ c []int
457+ }
458+
459+ func newBinaryIndexedTree(n int) *binaryIndexedTree {
460+ return &binaryIndexedTree{
461+ n: n,
462+ c: make([]int, n+1),
463+ }
464+ }
465+
466+ func (bit *binaryIndexedTree) update(x, delta int) {
467+ for x <= bit.n {
468+ bit.c[x] += delta
469+ x += x & -x
470+ }
471+ }
472+
473+ func (bit *binaryIndexedTree) query(x int) int {
474+ s := 0
475+ for x > 0 {
476+ s += bit.c[x]
477+ x -= x & -x
478+ }
479+ return s
480+ }
481+
482+ func minDeletions(s string, queries [][]int) []int {
483+ n := len(s)
484+ nums := make([]int, n)
485+ bit := newBinaryIndexedTree(n)
486+
487+ for i := 1; i < n; i++ {
488+ if s[i] == s[i-1] {
489+ nums[i] = 1
490+ bit.update(i+1, 1)
491+ }
492+ }
493+
494+ ans := make([]int, 0)
495+
496+ for _, q := range queries {
497+ if q[0] == 1 {
498+ j := q[1]
499+
500+ delta := (nums[j] ^ 1 - nums[j])
501+ nums[j] ^= 1
502+ bit.update(j+1, delta)
503+
504+ if j+1 < n {
505+ delta = (nums[j+1] ^ 1 - nums[j+1])
506+ nums[j+1] ^= 1
507+ bit.update(j+2, delta)
508+ }
509+ } else {
510+ l, r := q[1], q[2]
511+ ans = append(ans, bit.query(r+1)-bit.query(l+1))
512+ }
513+ }
514+
515+ return ans
516+ }
517+ ```
272518
519+ #### TypeScript
520+
521+ ``` ts
522+ class BinaryIndexedTree {
523+ n: number ;
524+ c: number [];
525+
526+ constructor (n : number ) {
527+ this .n = n ;
528+ this .c = Array (n + 1 ).fill (0 );
529+ }
530+
531+ update(x : number , delta : number ): void {
532+ while (x <= this .n ) {
533+ this .c [x ] += delta ;
534+ x += x & - x ;
535+ }
536+ }
537+
538+ query(x : number ): number {
539+ let s = 0 ;
540+ while (x > 0 ) {
541+ s += this .c [x ];
542+ x -= x & - x ;
543+ }
544+ return s ;
545+ }
546+ }
547+
548+ function minDeletions(s : string , queries : number [][]): number [] {
549+ const n = s .length ;
550+ const nums: number [] = Array (n ).fill (0 );
551+ const bit = new BinaryIndexedTree (n );
552+
553+ for (let i = 1 ; i < n ; i ++ ) {
554+ if (s [i ] === s [i - 1 ]) {
555+ nums [i ] = 1 ;
556+ bit .update (i + 1 , 1 );
557+ }
558+ }
559+
560+ const ans: number [] = [];
561+
562+ for (const q of queries ) {
563+ if (q [0 ] === 1 ) {
564+ const j = q [1 ];
565+
566+ let delta = (nums [j ] ^ 1 ) - nums [j ];
567+ nums [j ] ^= 1 ;
568+ bit .update (j + 1 , delta );
569+
570+ if (j + 1 < n ) {
571+ delta = (nums [j + 1 ] ^ 1 ) - nums [j + 1 ];
572+ nums [j + 1 ] ^= 1 ;
573+ bit .update (j + 2 , delta );
574+ }
575+ } else {
576+ const l = q [1 ],
577+ r = q [2 ];
578+ ans .push (bit .query (r + 1 ) - bit .query (l + 1 ));
579+ }
580+ }
581+
582+ return ans ;
583+ }
273584```
274585
275586<!-- tabs:end -->
0 commit comments