给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
思路:
使用动态规划:有dp[i][i] = true
dp[i][j] = s[i]==s[j]&&dp[i+1][j-1]
中心拓展法则枚举每个点为回文串中点,向两侧扩展。
复杂度分析:
动态规划:时间复杂度O(n)空间复杂度O(n)
中心拓展法:时间复杂度O(n),空间复杂度O(1)。 中心扩展法的复杂度实际比动态规划低的多,每个回文中心最多会向外扩展O(n)次
//动态规划
var longestPalindrome = function (s) {
let n = s.length;
if (n === 0) {
return "";
}
let dp = new Array(n).fill(undefined).map(() => new Array(n).fill(false));
let ans = '';
for (let i = n - 1; i >= 0; i--) {
for (let j = i; j < n; j++) {
if (s[i] === s[j] && (j - i < 2 || dp[i + 1][j - 1])) {
dp[i][j] = true;
if(j-i+1>ans.length){
ans = s.substring(i,j+1)
}
}
}
}
return ans;
};
//中心扩展法
var longestPalindrome = function(s) {
let length = s.length;
if(length < 2){
return s;
}
let [start, maxLength] = [0, 1];
//判断一个字符串是否为回文
function isPalindrome(left, right){
while(left>=0 && right<length && s[left] === s[right]){
if(right-left+1>maxLength){
maxLength = right-left +1;
start = left;
}
left --;
right ++;
}
}
for(let i=0; i<length; i++){
isPalindrome(i-1, i+1);
isPalindrome(i,i+1);
}
return s.substring(start, start + maxLength);
};