LintCode 算法(中等)最长回文子串
题目
给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。
样例
给出字符串 “abcdzdcab”,它的最长回文子串为 “cdzdc”。
挑战
O(n2) 时间复杂度的算法是可以接受的,如果你能用 O(n) 的算法那自然更好。
思路
由于能力有限O(n)算法实在是搞不定,而遍历所有字符串中子串算法时间复杂度度达到了O(n3),不符合性能要求,所以换个思路选择使用中心扩展进行判断。简单点说把字符串中每个子串当成是最长回文子串的中心,那么在其左右两则字符应当满足回文规则。如aba,abbac。
这里需要注意的是最长回文子串可能是偶数长度(abbac最长子串为abba)或奇数长度(aba最长子串为aba),在进行判断时逻辑有稍许不同。
奇数子串:只需把字符串中每个子串当成是最长回文子串的中心,向两边遍历是否满足回文规则即可
偶数子串:需将当前索引位index以及index+1字符合并看成最长回文子串的中心,向两边遍历是否满足回文规则即可
在字符串中可能同时出现满足回文条件的奇数子串,偶数子串。所以需要回文长度需要进行判断。
public class Solution {
/**
* @param s: input string
* @return: the longest palindromic substring
*/
public String longestPalindrome(String s) {
//中心扩展算法
String m="";
int index=0;
if(s.length()==1) return s;
//以index为中心点像两边扩展
while (index<s.length())
{
int front=index-1;
int last=index+1;
if(front<0 || last>s.length())
{
index++;
continue;
}
for(;front>=0 && last<s.length();front--,last++)
{
char left= s.charAt(front);
char rghit= s.charAt(last);
if(left!=rghit )
{
break;
}
}
int beginIndex=front+1;
int endIndex=last;
String temp=s.substring(beginIndex,endIndex);
m=temp.length()>m.length()?temp:m;
index++;
}
index=0;
//以index,index+1为中心点像两边扩展
while (index<s.length())
{
int front=index;
int last=index+1;
if(front<0 || last>s.length())
{
index++;
continue;
}
for(;front>=0 && last<s.length();front--,last++)
{
char left= s.charAt(front);
char rghit= s.charAt(last);
if(left!=rghit )
{
break;
}
}
int beginIndex=front+1;
int endIndex=last;
String temp=s.substring(beginIndex,endIndex);
m=temp.length()>m.length()?temp:m;
index++;
}
return m;
}
}