一、前言🌟
哈喽,小伙伴们,我是泽南👨🎓。不管你是准备跳槽还是在职苟着,都一起行动起来,顺应这个内卷时代干点该干的事儿👣。所以,赶紧跟着我的步伐卷起来吧⏰,变强从这一刻开始!➕🧈
二、题目介绍🌟
给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例 1:
输入: s = "babad"
输出: "bab"
解释: "aba" 同样是符合题意的答案。
示例 2:
输入: s = "cbbd"
输出: "bb"
提示:
1 <= s.length <= 1000s仅由数字和英文字母组成
解法一 :中心扩散法
解题思路: 两种情况 一种是回文子串长度为奇数(如aba,中心是b) 另一种回文子串长度为偶数(如abba,中心是b,b)
循环遍历字符串 对取到的每个值 都假设他可能成为最后的中心进行判断,也就是说从中间开始扩散,相同就继续向两侧扩散,但是切记,最后的结果要是循环上一次的值,因为while多执行了一次!
/**
* @param {string} s
* @return {string}
*/
var longestPalindrome = function(s) {
let max = ''
for(let i=0; i< s.length; i++) {
// 回文子串是 奇数
helper(i, i)
// 回文子串是 偶数
helper(i, i+1)
}
function helper(l, r) {
// 定义左右双指针
while(l>=0 && r< s.length && s[l] === s[r]) {
l--
r++
}
// 拿到回文字符, 注意 上面while满足条件后多执行了一次,所以需要l+1, r+1-1
const maxStr = s.slice(l + 1, r + 1 - 1);
// 取最大长度的回文字符
if (maxStr.length > max.length) max = maxStr
}
return max
};
时间复杂度: O(n)
空间复杂度: O(n)
解法二:动态规划
解题思路: 通过填充一个二维数组 dp,dp[i][j] 表示从索引 i 到 j 的子串是否是回文子串。算法首先处理单个字符和长度为2的子串,然后通过递推关系填充长度大于2的子串。最后返回找到的最长回文子串。
function longestPalindrome(s) {
const n = s.length;
let start = 0; // 回文子串起始位置
let maxLength = 1; // 最长回文子串长度
// 创建二维数组用于保存子问题的结果
const dp = Array.from(Array(n), () => Array(n).fill(false));
// 单个字符都是回文子串
for (let i = 0; i < n; i++) {
dp[i][i] = true;
}
// 检查长度为2的子串
for (let i = 0; i < n - 1; i++) {
if (s[i] === s[i + 1]) {
dp[i][i + 1] = true;
start = i;
maxLength = 2;
}
}
// 检查长度大于2的子串
for (let len = 3; len <= n; len++) {
for (let i = 0; i <= n - len; i++) {
const j = i + len - 1; // 子串的结束位置
if (s[i] === s[j] && dp[i + 1][j - 1]) {
dp[i][j] = true;
start = i;
maxLength = len;
}
}
}
// 返回最长回文子串
return s.substring(start, start + maxLength);
}
时间复杂度: O(n^2)
空间复杂度: O(n^2)
最后🌟:
☘️做你想做的人,没有时间限制,只要愿意,什么时候都可以start,
🍀你能从现在开始改变,也可以一成不变,这件事,没有规矩可言,你可以活出最精彩的自己。