携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情
题目
leetcode 5. 最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
示例:
输入: s = "babad"
输出: "bab"
解释: "aba" 同样是符合题意的答案。
题解
回文的意思是正着念和倒着念一样,比如abcba,正反都是一样的字符串我们就可以当作回文字符串。对于一个子串而言,如果它是回文串,并且长度大于2,那么将它首尾的两个字母去除之后,它仍然是个回文串。
暴力解法:
通过双指针遍历每一种字串,然后判断该字串是否是回文字符串,然后在所有回文子串中返回最长的一个即可。
var longestPalindrome = function (s) {
if(s.length === 1){
return s
}
const arr = s.split('');
let l = 0;
const len = arr.length;
let r = l + 1;
const res = [];
while (l < len - 1) {
while (r < len) {
const subArr = arr.slice(l, r + 1);
if (isPalindrome(subArr)) {
res.push(subArr.join(''))
}
r++;
}
l++;
r = l + 1;
}
if(res.length === 0){
return arr[0]
}
res.sort((a,b)=>a.length-b.length);
return res[res.length - 1]
};
function isPalindrome(arr) {
const subArr = [...arr].reverse();
if (JSON.stringify(subArr) === JSON.stringify(arr)) {
return true
}
return false;
}
代码详解
首先写一个辅助函数 isPalindrome 来帮助我们判断字符串是否是回文字符串。
我们定义变量l,r为快慢指针,res来保存回文子串。循环遍历每一个子串,将符合的回文子串加入到res数组中。最后返回长度最大的回文子串即可得出结果。
中心扩散:
从中间字符串开始往两边扩散,相比于暴力解法速度提升了很多。
var longestPalindrome = function (s) {
if(s.length === 1){
return s
}
const len = s.length;
let max = ''
for (let i = 0; i <len; i++) {
fn(i, i)
fn(i, i + 1)
}
function fn (l, r) {
while (l >= 0 && r < s.length && s[l] === s[r]) {
l--
r++
}
const maxStr = s.slice(l + 1, r)
if (maxStr.length > max.length) {
max = maxStr
}
}
return max
}
代码详解
首先写一个辅助函数fn来完成扩散的运算,有两种情况一种是奇数个字符串,一种是偶数个字符串所以执行两次来完成整个回文子串的运算。