var longestPalindrome = function (s) {
let res = '';
for (let i = 0; i < s.length; i++) {
for (let j = i, k = i; j >= 0 && k < s.length && s[j] === s[k]; j-- , k++) {
if (res.length < k - j + 1) res = s.substr(j, k - j + 1);
}
for (let j = i, k = i + 1; j >= 0 && k < s.length && s[j] === s[k]; j-- , k++) {
if (res.length < k - j + 1) res = s.substr(j, k - j + 1);
}
}
return res;
};
复制代码
ma na cher
马拉车名字来源奇回文串数组
aba
#a#b#a#
复制代码
偶回文串缓存
abba
#a#b#b#a#
复制代码
id
: 容纳节点i最大回文子串的中心位置mx
: 上一个对称轴+它的回文半径p
: 回文半径数组p[i] = mx > i ? Math.min(p[2 * id - i], mx - i) : 1;
解释:学习
mx > i
,说明i
在上一个元素回文半径内,那i
就对应一个j
j = 2 * id - i
id = 3, i = 4, j = 2, j = 2 * 3 - 4 = 2
p[2 * id - i]
,是j
的对称半径,mx - i
是 以i
对对称中心的对称半径Math.min(p[2 * id - i], mx - i)
p[2 * id - i] > mx - i
, 说明j
的对称半径大于了mx
,即超过了mx
,只能截取mx
以内的,便是mx-i
p[2 * id - i] < mx - i
,说明j
的回文半径在mx
以内,所以p[i]
取p[2 * id - i]
p[i]
确定是回文的,而后左右判断,是否回文,再++
j
的回文半径,至关于用了缓存临时变量p[i] + i > mx
id
,上一个回文对称点+
回文半径mx
function longestPalindrome(s) {
let str = s.split('').reduce((prev, item) => prev + item + '#', '#');
let id = 0, mx = 0, p = [];
let newLen = str.length;
// p = [x,x] 存的index的回文半径,mx 是上一个元素+回文半径
for (let i = 0; i < newLen; i++) {
p[i] = mx > i ? Math.min(p[2 * id - i], mx - i) : 1;
// i + p[i] 与 i - p[i], 左右对比,p[i]做为一个变量增加
// 控制左右是否溢出
while (
str[i + p[i]] === str[i - p[i]]
&& i - p[i] >= 0
&& i + p[i] < newLen
) { p[i]++ }
if (p[i] + i > mx) {
id = i;
mx = id + p[i];
}
}
const c_index = p.findIndex(it => Math.max(...p) === it);
const s_str = str.slice(c_index - (p[c_index] - 1), c_index + p[c_index]);
return s_str.replace(/\#/g, '');
}
复制代码
注意点:ui
let size = str.length
,关键字在leetcode里面报内部错误,😓