|
3 | 3 | * SC: O(n)
|
4 | 4 | * */
|
5 | 5 | function countSubstrings(s: string): number {
|
6 |
| - const t = "#" + s.split("").join("#") + "#"; |
7 |
| - const n = t.length; |
8 |
| - const p = new Array(n).fill(0); |
| 6 | + const str = "#" + s.split("").join("#") + "#"; |
| 7 | + const len = str.length; |
| 8 | + const pit = new Array(len).fill(0); |
9 | 9 | let center = 0,
|
10 | 10 | right = 0,
|
11 |
| - l = 0; |
| 11 | + result = 0; |
12 | 12 |
|
13 |
| - const mirror = (i: number, p: number[], c: number, r: number) => { |
14 |
| - return Math.min(r - i, p[c * 2 - i]); |
15 |
| - }; |
16 |
| - |
17 |
| - const isRightBound = (i: number, p: number[], n: number) => { |
18 |
| - return i + p[i] + 1 < n; |
19 |
| - }; |
20 |
| - |
21 |
| - const isLeftBound = (i: number, p: number[]) => { |
22 |
| - return i - p[i] - 1 >= 0; |
23 |
| - }; |
24 |
| - |
25 |
| - const isPalindrome = (i: number, p: number[], t: string) => { |
26 |
| - return t[i + p[i] + 1] === t[i - p[i] - 1]; |
27 |
| - }; |
28 |
| - |
29 |
| - const isLongest = (i: number, p: number[], r: number) => { |
30 |
| - return i + p[i] > r; |
31 |
| - }; |
32 |
| - |
33 |
| - const calcTotal = (i: number, p: number[]) => { |
34 |
| - return Math.floor((p[i] + 1) / 2); |
35 |
| - }; |
36 |
| - |
37 |
| - for (let i = 0; i < n; i++) { |
| 13 | + for (let i = 0; i < len; i++) { |
| 14 | + // Set pit[i] |
38 | 15 | if (i < right) {
|
39 |
| - p[i] = mirror(i, p, center, right); |
| 16 | + pit[i] = Math.min(right - i, pit[center * 2 - i]); |
40 | 17 | }
|
41 | 18 |
|
| 19 | + // Expand around i |
42 | 20 | while (
|
43 |
| - isRightBound(i, p, n) && |
44 |
| - isLeftBound(i, p) && |
45 |
| - isPalindrome(i, p, t) |
| 21 | + i + pit[i] + 1 < len && |
| 22 | + i - pit[i] - 1 >= 0 && |
| 23 | + str[i + pit[i] + 1] === str[i - pit[i] - 1] |
46 | 24 | ) {
|
47 |
| - p[i]++; |
| 25 | + pit[i]++; |
48 | 26 | }
|
49 | 27 |
|
50 |
| - if (isLongest(i, p, right)) { |
| 28 | + // Update center and right |
| 29 | + if (i + pit[i] > right) { |
51 | 30 | center = i;
|
52 |
| - right = i + p[i]; |
| 31 | + right = i + pit[i]; |
53 | 32 | }
|
54 | 33 |
|
55 |
| - l += calcTotal(i, p); |
| 34 | + // Add to result |
| 35 | + result += Math.floor((pit[i] + 1) / 2); |
56 | 36 | }
|
57 | 37 |
|
58 |
| - return l; |
| 38 | + return result; |
59 | 39 | }
|
0 commit comments