Skip to content

Commit 0780662

Browse files
committed
⚡ [647] Manacher's algorithm
1 parent 2585320 commit 0780662

File tree

2 files changed

+140
-58
lines changed

2 files changed

+140
-58
lines changed

647/my_solution.js

+70-34
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,89 @@
33
* @return {number}
44
*/
55
const countSubstrings = (s) => {
6-
// init the default count = 0 // s.len
7-
let l = 0, r = 0, count = 0;
6+
let count = 0;
87

9-
// while (l <= r && r < s.length) {
10-
while (l <= r) {
8+
// Manacher's algorithm
9+
// preprocess to add #
10+
processedS = `#`
11+
for (let i = 0; i < s.length; i++) {
12+
processedS += `${s[i]}#`;
13+
}
14+
console.log(processedS)
1115

12-
console.log(`l:${l}, r:${r} ?:${s.slice(l, r + 1)}`)
13-
if (undefined === s[r]) {
14-
console.log("not foudn alr")
16+
for (let i = 0; i < processedS.length; i++) {
17+
console.log(`-> i:${i}`)
18+
let l = 1; r = 1, tmpCount = 0;
19+
while (undefined !== processedS[i - l] && processedS[i - l] === processedS[i + r]) {
20+
console.log(`--> l:${l}, r:${r}, ${processedS[i - l]} === ${processedS[i + r]}`)
21+
tmpCount++;
1522
l++;
16-
continue;
23+
r++;
1724
}
1825

19-
if (isPalidrome(s.slice(l, r + 1))) {
20-
console.log(`this is a pal: ${s.slice(l, r + 1)}`)
21-
count++;
22-
}
26+
console.log("tmpCount")
27+
console.log(tmpCount)
2328

24-
r++;
2529

26-
if (r === s.length) {
27-
console.log("yo the ennd")
28-
l++;
29-
r = l;
30-
}
30+
count += Math.ceil(tmpCount / 2);
3131
}
3232

33-
console.log("count")
33+
34+
console.log(`>> ${s}:count`)
3435
console.log(count)
3536

3637
return count;
3738
}
3839

39-
// fn to findPalidrome while lr
40-
const isPalidrome = (str) => {
41-
let x = 0, y = str.length - 1;
42-
while (x <= y) {
43-
if (str[x] !== str[y]) return false;
44-
x++;
45-
y--;
46-
}
47-
48-
return true;
49-
}
50-
5140

5241
countSubstrings("abc") // 3
53-
countSubstrings("aaa") // 6
54-
countSubstrings("qwere") // 5
55-
countSubstrings("aba") // 4
42+
// countSubstrings("aaa") // 6
43+
// countSubstrings("qwere") // 6
44+
// countSubstrings("aba") // 4
45+
// countSubstrings("dnncbwoneinoplypwgbwktmvkoimcooyiwirgbxlcttgteqthcvyoueyftiwgwwxvxvg") // 6
46+
47+
// const countSubstrings = (s) => {
48+
// // init the default count = 0 // s.len
49+
// let l = 0, r = 0, count = 0;
50+
//
51+
// // while (l <= r && r < s.length) {
52+
// while (l <= r) {
53+
//
54+
// console.log(`l:${l}, r:${r} ?:${s.slice(l, r + 1)}`)
55+
// if (undefined === s[r]) {
56+
// console.log("not foudn alr")
57+
// l++;
58+
// continue;
59+
// }
60+
//
61+
// if (isPalidrome(s.slice(l, r + 1))) {
62+
// console.log(`this is a pal: ${s.slice(l, r + 1)}`)
63+
// count++;
64+
// }
65+
//
66+
// r++;
67+
//
68+
// if (r === s.length) {
69+
// console.log("yo the ennd")
70+
// l++;
71+
// r = l;
72+
// }
73+
// }
74+
//
75+
// console.log("count")
76+
// console.log(count)
77+
//
78+
// return count;
79+
// }
80+
//
81+
// // fn to findPalidrome while lr
82+
// const isPalidrome = (str) => {
83+
// let x = 0, y = str.length - 1;
84+
// while (x <= y) {
85+
// if (str[x] !== str[y]) return false;
86+
// x++;
87+
// y--;
88+
// }
89+
//
90+
// return true;
91+
// }

647/solution.js

+70-24
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,82 @@
22
* @param {string} s
33
* @return {number}
44
*/
5-
const countSubstrings = (s) => {
6-
let l = 0, r = 0, count = 0;
5+
const countSubstrings = (s) => { // Manacher's algorithm
6+
let modifiedString = '#';
7+
for (let i = 0; i < s.length; i++) {
8+
modifiedString += s[i] + '#';
9+
}
710

8-
while (l <= r) {
9-
if (undefined === s[r]) {
10-
l++;
11-
continue;
12-
}
13-
if (isPalidrome(s.slice(l, r + 1))) {
14-
count++;
11+
const n = modifiedString.length;
12+
const P = new Array(n).fill(0);
13+
let center = 0, right = 0;
14+
let count = 0;
15+
16+
for (let i = 0; i < n; i++) {
17+
if (i <= right) {
18+
const mirror = 2 * center - i;
19+
P[i] = Math.min(right - i, P[mirror]);
1520
}
1621

17-
r++;
22+
let leftIndex = i - (1 + P[i]);
23+
let rightIndex = i + (1 + P[i]);
24+
25+
while (leftIndex >= 0 && rightIndex < n && modifiedString[leftIndex] === modifiedString[rightIndex]) {
26+
P[i]++;
27+
leftIndex--;
28+
rightIndex++;
29+
}
1830

19-
if (r === s.length) {
20-
l++;
21-
r = l;
31+
if (i + P[i] > right) {
32+
center = i;
33+
right = i + P[i];
2234
}
35+
36+
count += Math.ceil(P[i] / 2);
2337
}
2438

2539
return count;
26-
}
27-
28-
const isPalidrome = (str) => {
29-
let x = 0, y = str.length - 1;
30-
while (x <= y) {
31-
if (str[x] !== str[y]) return false;
32-
x++;
33-
y--;
34-
}
40+
};
41+
42+
43+
// const countSubstrings = (s) => {
44+
// let l = 0, r = 0, count = 0;
45+
//
46+
// while (l <= r) {
47+
// if (undefined === s[r]) {
48+
// l++;
49+
// continue;
50+
// }
51+
//
52+
// if (isPalidrome(s.slice(l, r + 1))) {
53+
// count++;
54+
// }
55+
//
56+
// r++;
57+
//
58+
// if (r === s.length) {
59+
// l++;
60+
// r = l;
61+
// }
62+
// }
63+
//
64+
// console.log("count")
65+
// console.log(count)
66+
//
67+
// return count;
68+
// }
69+
//
70+
// const isPalidrome = (str) => {
71+
// let x = 0, y = str.length - 1;
72+
// while (x <= y) {
73+
// if (str[x] !== str[y]) return false;
74+
// x++;
75+
// y--;
76+
// }
77+
//
78+
// return true;
79+
// }
3580

36-
return true;
37-
}
81+
countSubstrings("aaa")
82+
countSubstrings("abcb")
83+
countSubstrings("qrwrw")

0 commit comments

Comments
 (0)