1.问题:
给定一个字符串,找到其最长回文子串
最长回文子串:一个字符串,从前往后读和从后往前读其结果相同。
2.思路:
思路1:暴力解法
从头开始遍历该字符串,对于其后面的每一个字符都与其自己进行比较,如果遇到与自己相同的字符串,则进行回文检查,而回文检查则是将中间的字符串取出来,然后对该字符串依次进行首尾对比,也就是说第一个字符要和最后一个字符相同,第二个字符要和倒数第二个字符相同,以此类推,如果有任何一个不相同,则说明该字符串不是回文字符串。
而如果是回文,则将该字符串记录下来,而后继续往后遍历,寻找下一个回文子串,再与当前的回文字串进行长度比较,保留长的字符串,以此类推,最后遍历完所有的字符,即找到了最长的回文字串。
该算法时间复杂度为O(n3)
代码实现:
public static string LongestPalindrome(string s)
{
string str="";
for (int i = 0; i < s.Length; i++)
{
string tempStr = s[i]+"";
for (int j = i+1; j < s.Length; j++)
{
tempStr += s[j];
if (s[i] == s[j])
{
// 回文检查
if (CheckHuiWen(s,i,j))
{
if (str.Length< tempStr.Length)
{
str = tempStr;
}
}
}
}
}
if (str.Equals(""))
{
return s[0]+"";
}
return str;
}
private static bool CheckHuiWen(string str,int i,int j)
{
int temp = (j-i)/2;
for (int k = 0; k <= temp; k++)
{
if (str[i+k] != str[j-k])
{
return false;
}
}
return true;
}
思路二:中心扩展法
从一个元素开始,依次从它的两边向外探索,直到找到其两边不相同的为止,就找到了该字符在该字符串中的最长回文,然后以此方法依次遍历所有的字符,即可找到最长回文字串。
C#实现:
string maxStr = "";
string res;
for (int i = 0; i < s.Length; i++)
{
int j = 1;
res = s[i]+"";
while (i - j >= 0 && i + j < s.Length)
{
if (s[i] == s[i + 1])// 偶数
{
res += s[i +1];
if (i + j + 1 >= s.Length || s[i - j] != s[i+j+1])
{
break;
}
else
{
if (res.Length > maxStr.Length)
{
maxStr = res;
}
j++;
}
}
else// 奇数
{
if (s[i - j] != s[i + j])// 不是回文
{
break;
}
else
{
res = s[i - j] + res;
res = res + s[i - j];
if (res.Length > maxStr.Length)
{
maxStr = res;
}
j++;
}
}
}
}
if (maxStr.Equals(""))
{
return s[0] + "";
}
return maxStr;