|
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