闲来无事,刷题玩耍~
题目如下: 求最长回文子串
Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
大意就是给你一个字符串,求其中最长的回文字串,最大长度1000.
王老菊说遇事不决莽一波 第一次上的算法是暴力求解,时间复杂度n^3,不出所料的超时了~
以下是AC的算法:
根据回文串的特点,在中轴两侧对应位置的字符应当相等。
将一个位置pos作为中轴,遍历两侧的字符,直到不相等或超出范围为止,即可求得以此pos为中轴的最长回文串。
以上情况仅适用于回文串的字符为奇数时,存在中轴字符。当回文串的字符数为偶数时,将pos和pos+1同时作为中轴,向两侧扩展遍历即可。
算法的时间复杂度为o(n^2),提交AC
代码如下,详见注释:
package leecode;
/**
* 最长回文字串
* Created by shizhida on 16/4/21.
*/
public class P5_Longest_Palindromic {
/**
* 求最长回文字串
* @param str
* @return
*/
public static String longestPalindromic(String str){
int maxlength = 0;
int lpos = 0,rpos = 0;
for(int i=0;i<str.length();i++){
//假设为奇
int len1 = searchAround(str,i,0);
//假设为偶
int len2 = searchAround(str,i,1);
if(len1>maxlength)
{
maxlength = len1;
lpos = i-len1/2;
rpos = i+len1/2+1;
}
if(len2>maxlength)
{
maxlength = len2;
lpos = i-len2/2+1;
rpos = i+len2/2+1;
}
}
System.out.println(maxlength);
return str.substring(lpos,rpos);
// return maxlength;
}
/**
* 从中心点开始校验左右
* @param str
* @param pos
* @param sub
* @return
*/
public static int searchAround(String str,int pos,int sub){
int l = 0,//左侧延伸
r = 0+sub,//右侧延伸
length=0;//最终长度
while(pos-l>=0&&pos+r<str.length()&&//超出范围
str.charAt(pos-l)==str.charAt(pos+r)//两侧不等
){
length = r+l;//长度为左+右+差值
//同步扩大范围
l++;
r++;
}
return length+1;//会漏掉中间一个(奇)或少算旁边一个(偶),所以都要+1
}
}