给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
暴力法
最容易想到的就是暴力破解,求出每一个子串,之后判断是不是回文,找到最长的那个。
求每一个子串时间复杂度O(N^2), 判断子串是不是回文O(N),两者是相乘关系,所以时间复杂度为O(N^3)。
public class Solution {
public string LongestPalindrome(string s) {
if (s == "") return s;
int len = s.Length;
int maxLen = 1;
int start = 0;
for(int i = 0; i < len; i++)
{
for(int j = i + 1; j < len; j++)
{
int tmp1 = i, tmp2 = j;
while (tmp1 < tmp2 && s[tmp1] == s[tmp2])
{
tmp1++;
tmp2--;
}
if (tmp1 >= tmp2 && j - i + 1 > maxLen)
{
maxLen = j - i + 1;
start = i;
}
}
}
return rs.Substring(start, maxLen);
}
}
中心扩展法
中心扩展就是把给定的字符串的每一个字母当做中心,向两边扩展,这样来找最长的子回文串。算法复杂度为O(N^2)。
需要考虑两种情况:
长度为奇数的回文串,比如a, aba, abcba
长度为偶数的回文串,比如aa, abba
public class Solution
{
public string LongestPalindrome(string s)
{
if (s == "") return s;
int len = s.Length;
int maxlen = 1;
int start = 0;
for(int i = 0; i < len; i++)
{
int j = i - 1, k = i + 1;
while (j >= 0 && k < len && s[j] == s[k])
{
if (k - j + 1 > maxlen)
{
maxlen = k - j + 1;
start = j;
}
j--;
k++;
}
}
for(int i = 0; i < len; i++)
{
int j = i, k = i + 1;
while (j >= 0 && k < len && s[j] == s[k])
{
if (k - j + 1 > maxlen)
{
maxlen = k - j + 1;
start = j;
}
j--;
k++;
}
}
return s.Substring(start, maxlen);
}
}