[leetcode]5.最长回文字符串
题目地址 https://leetcode-cn.com/problems/longest-palindromic-substring/
分析题目
题目需要找到最长回文字符串,最长这个特点可以通过max寄存器与temp值比较可得。回文字符串具有对称性的特点,对称可以找对称中心来解决。
除此之外还需要处理回文字符串长度为奇偶的情况。
算法用的是找对称中心然后从中心扩散的方法,其他的算法类似搞二维数组(太占空间了,事件复杂度也不突出)、马拉车算法(插入#时每个元素都要访问一遍,也很浪费时间)
代码与算法
初次设计的算法:从string的首个字符开始遍历,每个字符都查找一次奇数回文,一次偶数回文。
public string LongestPalindrome(string s)
{
int maxStringLength, tempStringLength;
int maxStringLeft, tempStringLeft, tempStringRight;
//max寄存器保存字符串长度和起始点就可以了,这是根据String.Substring方法决定的
//temp记录的left和right是扩散时的左右哦指针
//奇数判断开始
maxStringLength = 1;//不可为0,因为s="ab"时输出"a"
maxStringLeft = 0;
for (int i = 0; i < s.Length; i++)
{
tempStringLeft=tempStringRight = i;
tempStringLength = 1;
do
{
if (tempStringLength > maxStringLength)
{
maxStringLength = tempStringLength;
maxStringLeft = tempStringLeft;
}
tempStringLength = tempStringLength + 2;
tempStringLeft--;
tempStringRight++;
if (tempStringLeft < 0)
break;
if (tempStringRight == s.Length)
break;
} while (s[tempStringLeft] == s[tempStringRight]);
//使用do-while的原因是判断字符相等时,可能会出现数组下标溢出的情况
//所以要先判断是否溢出。
//偶数判断开始
tempStringLength = 2;//偶数判断的特殊性,需要判断下一位字符是否相等
tempStringLeft = i ;
tempStringRight = i + 1;
if (i == s.Length - 1)
continue;//判断溢出
if (s[i] != s[i + 1])
continue;//判断相等
do
{
if (tempStringLength > maxStringLength)
{
maxStringLength = tempStringLength;
maxStringLeft = tempStringLeft;
}
tempStringLength = tempStringLength + 2;
tempStringLeft--;
tempStringRight++;
if (tempStringLeft < 0)
break;
if (tempStringRight == s.Length)
break;
} while (s[tempStringLeft] == s[tempStringRight]);
}
return s.Substring(maxStringLeft, maxStringLength);
}
优化改进
上述算法将奇偶回文字符串分开判断,但写完代码后发现奇偶判断之间有比较高的耦合性,可以尝试合并。
两个判断的主要差异在于判断起始点,奇回文起始点为单个字符,偶回文起始点为两个字符。尝试将左右判断指针应用到起始点上。奇回文起始点为单个,左右判断指针同时指向这个字符,满足判断相同条件。偶回文起始点为两个,左右判断指针分别指两个字符。
改进后的代码:
public string LongestPalindrome(string s)
{
int maxStringLength;
int maxStringLeft;
maxStringLength = 1;
maxStringLeft = 0;
for (int i = 0; i < s.Length; i++)
{
CentralSpreading(s,i,i,1,ref maxStringLength,ref maxStringLeft);
CentralSpreading(s, i, i+1, 2, ref maxStringLength, ref maxStringLeft);
}
return s.Substring(maxStringLeft, maxStringLength);
}
public void CentralSpreading(string s,int tempStringLeft, int tempStringRight, int tempStringLength, ref int maxStringLength,ref int maxStringLeft)
{
while (tempStringLeft > -1 && tempStringRight < s.Length && s[tempStringLeft] == s[tempStringRight])
{
if (tempStringLength > maxStringLength)
{
maxStringLength = tempStringLength;
maxStringLeft = tempStringLeft;
}
tempStringLength = tempStringLength + 2;
tempStringLeft--;
tempStringRight++;
}
}
比较两次leetcode上性能提升了10%


浙公网安备 33010602011771号