题目五:
http://topic.youkuaiyun.com/u/20070930/11/fa87b186-148e-4cc3-a582-013562e64de0.html
求给定的字符串中最长回文的长度。
例如给定的字符串为:“abcbaba”,最长的回文为“abcba”,长度为5
Answer1:
O(nlogn)的算法参见 参考资料里面的《后缀数组+最长回文之串.pdf》
字符串s1的反转串s2,求s1和s2的最长公共子串。利用求最长公共子串的方法,还是采用后缀数组的数据结构,时间复杂度为O(nlogn)
Answer2:
O(nlogn)的算法
http://hi.baidu.com/cuifenghui/blog/item/a665553d10720ded3c6d97ec.html
/*
思路描述: 最长回文串是关于中心轴对称的,可以分成求
最长奇回文子串和最长偶回文子串。对于最长奇回文子串
可以从中间一个点向两边延伸的方法来找出以该点为中心
的最长奇回文串,通过枚举中心点的方法求出整个串最长
的奇回文串;对于偶回文串,可以通过给原字符串加入一些
"空白字符"组成一个新字符串,然后利用求奇回文串的方法
做出。本程序就是利用填充"空白字符"并枚举中心点的方法
来找出字符串中最长的回文子串,时间复杂度为o(n^2)。
*/
Answer3:
http://hi.baidu.com/guidee/blog/item/c8ce40cba18eba17be09e6b1.html
/*
* 题目:
* 1:判断字符串是否是回文
* 2:字符串最长回文子串
*
* */
public class Symmetric
{
public Symmetric()
{
}
/// <summary>
/// 1:判断字符串是否是回文
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public bool IsSymmetric(string str)
{
int i = 0;
int j = str.Length - 1;
while (i < j)
{
if (str[i] != str[j])
return false;
i++;
j--;
}
return true;
}
/// <summary>
/// 2:字符串最长回文子串,方法一:从中心开始向两边搜索对称字符。较高效
/// </summary>
/// <param name="str"></param>
/// <param name="startPos"></param>
/// <returns></returns>
public int GetMaxSymmetricLengthAndPos1(string str, out int startPos)
{
startPos = -1;
if (string.IsNullOrEmpty(str))
{
return 0;
}
int sameStartPos = 0;
int sameEndPos = 0;
int maxLen = 0;
while (sameStartPos < str.Length)
{
sameEndPos = sameStartPos;
//判断有没有连续相同的字符,没有,则直接跳过
while (sameEndPos + 1 < str.Length && str[sameEndPos + 1] == str[sameStartPos])
sameEndPos++;
//寻找重复字符两边对称的字母
int searchLeft = sameStartPos;
int searchRight = sameEndPos;
while (searchLeft - 1 >= 0 && searchRight + 1 < str.Length
&& str[searchLeft - 1] == str[searchRight + 1])
{
searchLeft--;
searchRight++;
}
//判断是否长度更大
if (searchRight - searchLeft + 1 > maxLen)
{
//保存更大长度和对应的起始位置
maxLen = searchRight - searchLeft + 1;
startPos = searchLeft;
}
//设置搜做新位置,重复字符后面第一个位置
sameStartPos = sameEndPos + 1;
}
return maxLen;
}
/// <summary>
/// 2:字符串最长回文子串,方法二:从两边开始向中心搜索对称字符。低效
/// </summary>
/// <param name="str"></param>
/// <param name="startPos"></param>
/// <returns></returns>
public void GetMaxSymmetricLengthAndPos2(string str, out int sameStartPos, out int count)
{
int begin = 0;
int end = str.Length - 1;
int max = 0;
count = 0;
sameStartPos = -1;
int max = 0;
for (; begin < str.Length - 1; begin++)
{
for (; end > begin; end--)
{
if (IsSymmetric(str, begin, end))
{
max = end - begin;
if (max > count)
{
count = max;
sameStartPos = begin;
}
break;
}
}
}
}
/// <summary>
/// 判断子串是否回文
/// </summary>
/// <param name="str"></param>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <returns></returns>
public bool IsSymmetric(string str, int begin, int end)
{
int i = begin, j = end;
for (; i < j; i++, j--)
{
if (str[i] != str[j])
{
return false;
}
}
return true;
}
}
}