本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
给你一个字符串
s,找到s中最长的回文子串。
输入: s = "babad"
输出: "bab"
解释: "aba" 同样是符合题意的答案。
回文串:正着读和反着读都一样的字符串
解题思路
思路一
我们先从左边的第一个字符开始遍历,利用中心扩散法,核心思路回文串主要分为偶数和奇数,回文串为偶数个的时候
l=i,r=i+1,遇到相同的就直接往两边走,并且判断res.length是不是小于最长回文串的长度r-l-1, 满足条件就截取字符串, 回文串为奇数时,l=i-1,r=i+1,其余情况同上,边界点为[l+1,R-1],所以最长回文子串的长度为R-1-(l+1)+1=R-L-1
var longestPalindrome = function(s) {
let res='';
for(let i=0;i<s.length;i++){
let l=i-1, r=i+1;
while(l>=0 && r<s.length && s[l]===s[r]) l--,r++;
if(res.length <r-l-1) res=s.substr(l+1,r-l-1);
l=i,r=i+1;
while(l>=0 && r<s.length && s[l]===s[r]) l--,r++;
if(res.length <r-l-1) res=s.substr(l+1,r-l-1);
}
return res;
};
思路二
我们首先判断字符串为空串或者单字符的情况,直接返回原字符串,回文的状态转移方程是
dp[i][j] = s[i] === s[j] && (j - i <= 2 || dp[i + 1] [j - 1] === true),这个题使用的方法是从0点开始取右边index从1到n-1,依次计算出每一个的子范围的回文情况,确认是回文了之后,在判断最大的长度
var longestPalindrome = function(s) {
if(s.length < 2){
return s;
}
let maxLen = 1;
let maxStart = 0;
let maxEnd = 0;
const length = s.length;
const dp = Array.from({length}).map(_=>new Array(length).fill(false));
for(let r = 1; r < length; r++){
for(let l = 0; l < r; l++){
if(s[r] === s[l] && (r - l <= 2 || dp[l + 1] [r - 1])){
dp[l][r] = true;
if(r -l + 1 > maxLen){
maxStart = l;
maxEnd = r;
maxLen = r - l + 1;
}
}
}
}
return s.substring(maxStart, maxEnd + 1);
};