出题指数(最大5):⭐⭐⭐⭐⭐
题目
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
题解
中心扩展算法——此题动态规划法的改进方法
事实上,只需使用恒定的空间,我们可以在 O(n^2)的时间内解决这个问题。
我们观察到回文中心的两侧互为镜像。因此,回文可以从它的中心展开,并且只有 2n - 1个这样的中心。
你可能会问,为什么会是 2n - 1个,而不是 n个中心?原因在于所含字母数为偶数的回文的中心可以处于两字母之间(例如“abba”
的中心在两个b
之间)。
复杂度分析
时间复杂度:O(n^2)。由于围绕中心来扩展回文会耗去 O(n)的时间,所以总的复杂度为 O(n^2)。
空间复杂度:O(1)。
JavaScript实现
var longestPalindrome = function(s) {
let result = "";
if(s === '') return '';
if(s.length === 1) return s;
for (let i = 0; i < s.length - 1; i++) {
// 子串长度奇数和偶数都搜索一遍
let a = maxSubstring(i, i);
let b = maxSubstring(i, i + 1);
let temp = a.length > b.length ? a : b;
result = result.length > temp.length ? result : temp;
}
return result;
// 寻找某个对称轴为中心的最长回文子串
function maxSubstring(left, right) {
while (left >= 0 && right < s.length) {
if (s[left] === s[right]) {
left--;
right++;
}
else break;
}
// 使用slice的时候是左闭右开结构,所以left要+1指向子串第一个字符
left++;
// right到末尾使用slice会越界,单独考虑
if (right === s.length){
// console.log('1 '+s.slice(left));
return s.slice(left);
}
// console.log('2 '+s.slice(left,right));
return s.slice(left, right);
}
};
console.log("longestPalindrome('aabacc')", longestPalindrome('aabacc')); // aba
console.log("longestPalindrome('aabaa')", longestPalindrome('aabaa')); // aabaa
console.log("longestPalindrome('cbbd')", longestPalindrome('cbbd')); //bb
做题心得
竟然一发入魂,一次提交就过了,666
js的灵活性是真的方便,函数里面可以放闭包,而且由于函数提升,还可以把闭包放在最后面,代码整洁很多