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裏面報內部錯誤,😓