给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
示例 4:
输入:s = "ac"
输出:"a"
方案一:暴力解法(psleetcode会超时)
function isPalindrome($str) {
return $str == strrev($str);
}
/**
* @param String $s
* @return String
*/
function longestPalindrome1($s) {
if ($this->isPalindrome($s)) {
return $s;
}
$len = strlen($s);
$res = [];
for ($i=0;$i<$len;$i++) {
for ($j=1;$j<=$len;$j++) {
$str = substr($s, $i, $j);
if ($this->isPalindrome($str)) {
$res[] = $str;
$res = array_unique($res);
}
}
}
$max = 0;
foreach ($res as $key => $item) {
if (strlen($item) > strlen($res[$max])) {
$max = $key;
}
}
return $res[$max];
}
方案二:
function get_max_palindrome1($str)
{
$len = strlen($str);
$res = [];// 结果数组
$res2= [];// 偶数长度的结果
// 使用array_unshift的目的是为了从前向数组插入每一次找到的答案。也可以直接更新单个元素数组,就是只要当前取到的字符串比原来的长,就把原来的覆盖掉
// 使用多维数组不是必须的,以为数组或者变量也可以。这里就是做一个简单的记录,可以微调一下,多完成另一个功能
array_unshift($res, $str[0]);// 默认将第一个字符作为最长回文串写入数组
array_unshift($res2, '');// 默认一个空字符串,长度为0,初始化
for ($i = 1; $i < $len ; $i++) {// 从第二个开始操作,因为第一个左边没有字符,只能算本身长度为1的回文串
// 针对奇数长度的最长回文串
$left = $right = $i;// 从中间向两边扩展,默认起始位置为中间的这个位置
$tmp = $str[$i];// 临时回文串,用于中间数据处理,默认是当前字符串
while ($left > 0 and $right < $len - 1) {// 限定,只要有任何一边到头,循环结束
$left--;// 左边向左扩展
$right++;// 右边向👉扩展
if ($str[$left] == $str[$right]) {// 如果扩展以后左右相等,说明当前是回文串
$tmp = $str[$left] . $tmp . $str[$right];// 将当前符合的回文串组合在一起
if (strlen($tmp) > strlen($res[0])) {// 如果当前得到的回文串比原来数组中最长的回文串长,则记录该回文串信息
array_unshift($res, $tmp);// 将当前回文串信息(长度和内容)记录在结果数组中
}
} else {// 不相等,就不用处理后续了,跳出循环
break;
}
}
// 针对偶数长度的最长回文串
$left2 = $i - 1;
$right2 = $i;// 从中间向两边扩展,默认起始位置为中间的这个位置
if ($str[$i] == $str[$i-1]) {// 如果当前的字符和他前一个字符相等,说明很可能是一个偶数长度的回文串
$tmp2 = $str[$i-1] . $str[$i];// 两个拼一起,记录下来作为初始字符串
if (count($res2) == 1) {// 如果只有一个,说明是只有一个默认的无效的元素
array_unshift($res2, $tmp2);// 相当于真正有效的第一个偶数长度的字符串
}
while ($left2 > 0 and $right2 < $len - 1) {
$left2--;
$right2++;
if ($str[$left2] == $str[$right2]) {// 如果扩展以后左右相等,说明当前是回文串
$tmp2 = $str[$left2] . $tmp2 . $str[$right2];// 将当前符合的回文串组合在一起
if (strlen($tmp2) > strlen($res2[0])) {// 如果当前得到的回文串比原来数组中最长的回文串长,则记录该回文串信息
array_unshift($res2, $tmp2);// 将当前回文串信息(长度和内容)记录在结果数组中
}
} else {// 不相等,就不用处理后续了,跳出循环
break;
}
}
}
}
// 结果数组中,第一个元素就是str是最长的回文串,谁长就返回谁
if (strlen($res[0]) >= strlen($res2[0])) {
return $res[0];// 奇数长度回文数组
} else {
return $res2[0];// 偶数长度回文数组
}
}
function longestPalindrome($s) {
$len = strlen($s);
$res = []; // 结果数组
$res2= [];// 偶数长度的结果
// 使用array_unshift的目的是为了从前向数组插入每一次找到的答案。也可以直接更新单个元素数组,就是只要当前取到的字符串比原来的长,就把原来的覆盖掉
// 使用多维数组不是必须的,以为数组或者变量也可以。这里就是做一个简单的记录,可以微调一下,多完成另一个功能
array_unshift($res, $s[0]);// 默认将第一个字符作为最长回文串写入数组
array_unshift($res2, '');// 默认一个空字符串,长度为0,初始化
for ($i = 1; $i < $len; $i++) {// 从第二个开始操作,因为第一个左边没有字符,只能算本身长度为1的回文串
// 针对奇数长度的最长回文串 aba
$left = $i;
$right = $i;
$tmp = $s[$i];
while ($left > 0 && $right < $len-1) {
$left--;
$right++;
if ($s[$left] == $s[$right]) {
$tmp = $s[$left] . $tmp . $s[$right];// 将当前符合的回文串组合在一起
if (strlen($tmp) > strlen($res[0])) {
array_unshift($res, $tmp);
}
} else {
break;
}
}
// 针对偶数长度的最长回文串
$left2 = $i - 1;
$right2 = $i;// 从中间向两边扩展,默认起始位置为中间的这个位置
if ($s[$left2] == $s[$right2]) {
$tmp2 = $s[$left2] . $s[$right2];
if (count($res2) == 1) {// 如果只有一个,说明是只有一个默认的无效的元素
array_unshift($res2, $tmp2);// 相当于真正有效的第一个偶数长度的字符串
}
while ($left2 > 0 && $right2 < $len-1) {
$left2--;
$right2++;
if ($s[$left2] == $s[$right2]) {
$tmp2 = $s[$left2] . $tmp2 . $s[$right2];
if (strlen($tmp2) > strlen($res[0])) {
array_unshift($res, $tmp2);
}
} else {
break;
}
}
}
}
return strlen($res[0]) >= strlen($res2[0]) ? $res[0] : $res2[0];
}