|
16 | 16 | <pre>
|
17 | 17 | <strong>Input:</strong> s = "babacc", queryCharacters = "bcb", queryIndices = [1,3,3]
|
18 | 18 | <strong>Output:</strong> [3,3,4]
|
19 |
| -<strong>Explanation:</strong> |
| 19 | +<strong>Explanation:</strong> |
20 | 20 | - 1<sup>st</sup> query updates s = "<u>b<strong>b</strong>b</u>acc". The longest substring consisting of one repeating character is "bbb" with length 3.
|
21 |
| -- 2<sup>nd</sup> query updates s = "bbb<u><strong>c</strong>cc</u>". |
| 21 | +- 2<sup>nd</sup> query updates s = "bbb<u><strong>c</strong>cc</u>". |
22 | 22 | The longest substring consisting of one repeating character can be "bbb" or "ccc" with length 3.
|
23 | 23 | - 3<sup>rd</sup> query updates s = "<u>bbb<strong>b</strong></u>cc". The longest substring consisting of one repeating character is "bbbb" with length 4.
|
24 | 24 | Thus, we return [3,3,4].
|
@@ -367,6 +367,91 @@ public:
|
367 | 367 | };
|
368 | 368 | ```
|
369 | 369 |
|
| 370 | +### **Go** |
| 371 | +
|
| 372 | +```go |
| 373 | +type segmentTree struct { |
| 374 | + str []byte |
| 375 | + mx []int |
| 376 | + lmx []int |
| 377 | + rmx []int |
| 378 | +} |
| 379 | +
|
| 380 | +func newSegmentTree(s string) *segmentTree { |
| 381 | + n := len(s) |
| 382 | + t := &segmentTree{ |
| 383 | + str: []byte(s), |
| 384 | + mx: make([]int, n<<2), |
| 385 | + lmx: make([]int, n<<2), |
| 386 | + rmx: make([]int, n<<2), |
| 387 | + } |
| 388 | + t.build(0, 0, n-1) |
| 389 | + return t |
| 390 | +} |
| 391 | +
|
| 392 | +func (t *segmentTree) build(x, l, r int) { |
| 393 | + if l == r { |
| 394 | + t.lmx[x] = 1 |
| 395 | + t.rmx[x] = 1 |
| 396 | + t.mx[x] = 1 |
| 397 | + return |
| 398 | + } |
| 399 | + m := int(uint(l+r) >> 1) |
| 400 | + t.build(x*2+1, l, m) |
| 401 | + t.build(x*2+2, m+1, r) |
| 402 | + t.pushup(x, l, m, r) |
| 403 | +} |
| 404 | +
|
| 405 | +func (t *segmentTree) pushup(x, l, m, r int) { |
| 406 | + lch, rch := x*2+1, x*2+2 |
| 407 | + t.lmx[x] = t.lmx[lch] |
| 408 | + t.rmx[x] = t.rmx[rch] |
| 409 | + t.mx[x] = max(t.mx[lch], t.mx[rch]) |
| 410 | + // can be merged |
| 411 | + if t.str[m] == t.str[m+1] { |
| 412 | + if t.lmx[lch] == m-l+1 { |
| 413 | + t.lmx[x] += t.lmx[rch] |
| 414 | + } |
| 415 | + if t.rmx[rch] == r-(m+1)-1 { |
| 416 | + t.rmx[x] += t.rmx[lch] |
| 417 | + } |
| 418 | + t.mx[x] = max(t.mx[x], t.rmx[lch]+t.lmx[rch]) |
| 419 | + } |
| 420 | +} |
| 421 | +
|
| 422 | +func (t *segmentTree) update(x, l, r, pos int, val byte) { |
| 423 | + if l == r { |
| 424 | + t.str[pos] = val |
| 425 | + return |
| 426 | + } |
| 427 | + m := int(uint(l+r) >> 1) |
| 428 | + if pos <= m { |
| 429 | + t.update(x*2+1, l, m, pos, val) |
| 430 | + } else { |
| 431 | + t.update(x*2+2, m+1, r, pos, val) |
| 432 | + } |
| 433 | + t.pushup(x, l, m, r) |
| 434 | +} |
| 435 | +
|
| 436 | +func max(x, y int) int { |
| 437 | + if x > y { |
| 438 | + return x |
| 439 | + } |
| 440 | + return y |
| 441 | +} |
| 442 | +
|
| 443 | +func longestRepeating(s string, queryCharacters string, queryIndices []int) []int { |
| 444 | + ans := make([]int, len(queryCharacters)) |
| 445 | + t := newSegmentTree(s) |
| 446 | + n := len(s) |
| 447 | + for i, c := range queryCharacters { |
| 448 | + t.update(0, 0, n-1, queryIndices[i], byte(c)) |
| 449 | + ans[i] = t.mx[0] |
| 450 | + } |
| 451 | + return ans |
| 452 | +} |
| 453 | +``` |
| 454 | + |
370 | 455 | ### **TypeScript**
|
371 | 456 |
|
372 | 457 | ```ts
|
|
0 commit comments