版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/asdasd3418/article/details/78781903
最长回文串
问题:
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
大意:
给定一个字符串s,找到s的最长回文子串。字符串的最大长度为1000.
示例:
Example:
Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.Example:
Input: “cbbd”
Output: “bb”
解题方案:
这道题的解题思路有很多:
1. 求出每个子串,然后判断其是否为回文串。时间复杂度为O(n2)
2. 遍历字符串每个字符,从这个字符向两边校验是否相等。时间复杂度为O(n2)
3. Manacher(马拉车算法),时间复杂度为O(n),个人觉得是个很有意思的算法,附上算法详解(自己也是新学的,所以就不分析了) http://blog.csdn.net/dyx404514/article/details/42061017
manacher算法java版(accepted)
static class Manacher {
private int[] len;//长度为i最长回文串的长度=len - 1,从左往右计算
private String s;//原字符串
private char[] t;//将字符串中间插入'#'后的字符数组。
public Manacher(String s) {
super();
this.s = s;
}
/**
* 预处理字符串,例如,s="abba" 那么t="$#a#b#b#a#@"
* $和@是为了防止边界检测
*/
private void preprocess() {
t = new char[s.length() * 2 + 3];
t[0] = '$';
t[s.length() * 2 + 2] = '@';
for (int i = 0; i < s.length(); i++) {
t[2*i + 1] = '#';
t[2*i + 2] = s.charAt(i);
}
t[s.length()*2 + 1] = '#';
}
public void process() {
preprocess();
len = new int[t.length];
int center = 0, right = 0;
for (int i = 1; i < t.length - 1; i++) {
int mirror = 2*center - i;
if (right > i) {
len[i] = Math.min(right - i, len[mirror]);
}
while (t[i + (1 + len[i])] == t[i - (1 + len[i])]) {
len[i]++;
}
if (i + len[i] > right) {
center = i;
right = i + len[i];
}
}
}
public String longestPalindromicSubstring() {
int length = 0;
int center = 0;
for (int i = 1; i < len.length - 1; i++) {
if (len[i] > length) {
length = len[i];
center = i;
}
}
return s.substring((center - 1 -length) / 2, (center - 1 +length) / 2);
}
public static void main(String[] args) {
String s = "ababaca";
Manacher manacher = new Manacher(s);
manacher.process();
String str = manacher.longestPalindromicSubstring();
System.out.println(str);
}
}