给你一个字符串
s
,找到s
中最长的 回文 子串。
解法1 暴力解法
思路
判断回文串用双指针即可,把它抽出来作为一个函数。然后两层循环即可、为什么要两层循环?是为了避免漏掉从 i
开始到中间某个索引是回文串。
暴力解法可以ac。
代码
function longestPalindrome(s: string): string {
let result = "";
for (let i = 0; i < s.length; i++) {
for (let j = i + 1; j <= s.length; j++) {
const temp = s.substring(i, j); // s[i..j-1]
if (temp.length < result.length) {
continue;
}
if (temp.length > result.length && isPalindrome(temp)) {
result = temp;
}
}
}
return result;
};
function isPalindrome(s: string): boolean {
// 判断是否是回文
let i = 0;
let j = s.length - 1;
while (i < j) {
if (s[i] !== s[j]) {
return false;
}
i++;
j--;
}
return true;
}
时空复杂度
时间复杂度:O(n^3)
,两层循环为 O(n^2)
,判断回文串 isPalindrome
是 O(n)
空间复杂度:O(n)
解法2 中心扩展算法
思路
因为回文串具有对称性,所以如果找到一个中点,向两边扩展最有效率。
而回文也可以分成两种情况:奇数长度回文 aba
和偶数长度回文 abba
。
所以在遍历时也要分两种情况:以 i
为中心(单字符);以 i
和 i+1
为中心(双字符)。
然后再判断其长度更新答案即可。
代码
function longestPalindrome(s: string): string {
if (s.length < 2) return s;
let result = "";
for (let i = 0; i < s.length; i++) {
const odd = expandAroundCenter(s, i, i);
const even = expandAroundCenter(s, i, i + 1);
const longer = odd.length > even.length ? odd : even;
if (longer.length > result.length) {
result = longer;
}
}
return result;
};
function expandAroundCenter(s: string, left: number, right: number): string {
// 向两边扩展寻找回文
while (left >= 0 && right < s.length && s[left] === s[right]) {
left--;
right++;
}
return s.substring(left + 1, right);
}
时空复杂度
时间复杂度:O(n^2)
空间复杂度:O(1)