题目:
给出一个字符串S,找到一个最长的连续回文串。
注意可有2中形态:aba(奇数型) 或 abba(偶数型)
解法一:逐个遍历法:
<?php
$str = "ababa";
$re = longestPalindrome($str);
function preProcess($str) {
$n = strlen($str);
$ret = "";
for($i = 0; $i < $n; $i++) {
$ret .= "#".substr($str,$i,1);
}
$ret .= "#";
return $ret;
}
function longestPalindrome($str) {
$s = preProcess($str);
$n = strlen($s);
$p = array();
$maxLen = 0;
$center = 0;
for($i = 1; $i < $n-1; $i++) {
$p[$i] = 0;
$j = 1;
while($i-$j >= 0 && $i+$j <= $n-1 && $s[$i-$j] == $s[$i+$j]) {
$p[$i]++;
$j++;
}
if($p[$i] > $maxLen) {
$maxLen = $p[$i];
$center = $i;
}
echo "i:$i p[$i]:$p[$i] center:$center maxLen:$maxLen<br>";
}
echo substr($str,($center)/2-$maxLen/2,$maxLen);
}
解法二: Manacher’s Algorithm
参考:http://blog.csdn.net/hopeztm/article/details/7932245
参考:http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html
<?php
$str = "aaaa";
$re = longestPalindrome($str);
function preProcess($str) {
$n = strlen($str);
$ret = "";
for($i = 0; $i < $n; $i++) {
$ret .= "#".substr($str,$i,1);
}
$ret .= "#";
return $ret;
}
function longestPalindrome($str) {
$s = preProcess($str);
$n = strlen($s);
$p = array();
$maxLen = 0;
$center = 0;
$right = 0;
for($i = 1; $i < $n-1; $i++) {
$i_mirror = 2*$center - $i;
$p[$i] = $i<$right ? min($p[$i_mirror],$right-$i) : 0;
while($i-1-$p[$i] >= 0 && $i+1+$p[$i] <= $n-1 && $s[$i+1+$p[$i]] == $s[$i-1-$p[$i]]) {
echo "$i";
echo "<br>";
$p[$i]++;
}
if($right-$i < $p[$i]){
$center = $i;
$right = $i + $p[$i];
}
echo "i:$i right:$right p[$i]:$p[$i] center:$center <br>";
if($p[$i] > $maxLen) {
$maxLen = $p[$i];
$centerIndex = $i;
}
}
echo substr($str,($centerIndex-$maxLen)/2,$maxLen);
}