给你一个字符串
s,找到s中最长的回文子串。 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
思路:
-
- 每个下标为中心点往两边扩
-
- 但是回文里面如果再套回文,那么大回文两边的小回文直径是一样的,所以可以减少一些计算量来加速
-
- 如果大回文左侧的回文超出了边界,那么大回文右侧的小回文最多是R-i
/**
* @param {string} s
* @return {string}
*/
var longestPalindrome = function (s) {
if (!s || s.length == 0) return ''
let str = manacherString(s)
let pArr = new Array(str.length).fill({}).map(_ => {
return {
len: 0,
palindrome: ''
}
}), C = -1, R = -1, max = 0;
for (let i = 0; i < str.length; i++) {
pArr[i].len = R > i ? Math.min(pArr[2 * C - i].len, R - i) : 1;
while (i + pArr[i].len < str.length && i - pArr[i].len > -1) {// 如果不符合就超出两端,结束
if (str[i + pArr[i].len] == str[i - pArr[i].len]) {
pArr[i].palindrome = str.slice(i - pArr[i].len,
i + pArr[i].len + 1)
pArr[i].len++;
} else {
break;
}
}
if (i + pArr[i].len > R) {
R = i + pArr[i].len;
C = i;
}
max = Math.max(max, pArr[i].len)
}
pArr.sort((a, b) => b.len - a.len)
let ans = pArr[0].palindrome.filter(i => {
return i != '#'
})
// return max - 1;
return ans.join('')
};
function manacherString(str) {
let strArr = str.split('');
let res = new Array(strArr.length * 2 + 1)
let index = 0;
for (let i = 0; i < res.length; i++) {
res[i] = (i & 1) == 0 ? '#' : strArr[index++]
}
return res
}