题意
解题思路:
- 动态规划三部曲:
- dp状态定义:dp[i][j] 字符串从i到j是否是回文串,如果是,当前长度是j - i + 1
- dp初始化:$res = $s[0];
- dp状态转移方程: s[i] == s[j] dp[i][j] = dp[i+1][j-1]//回文串的子串也是回文串:babab
PHP 代码实现
class Solution { public $res = ''; public $max = 0; /** * @param String $s * @return String */ function longestPalindrome($s) { if (strlen($s) <= 1) return $s; for ($i = 0; $i < strlen($s); $i++) { $this->extendByCenter($s, $i, $i);//aba $this->extendByCenter($s, $i, $i + 1);//abba } return $this->res; } //暴力法 function longestPalindrome1($s) { $len = strlen($s); if ($len < 2) return $s; $maxLen = 1; $res = substr($s, 0, 1); for ($i = 0; $i < $len - 1; $i++) { for ($j = $i + 1; $j < $len; $j++) { if ($j - $i + 1 > $maxLen && $this->valid($s, $i, $j)) { $maxLen = $j - $i + 1; $res = substr($s, $i, $j - $i + 1); } } } return $res; } // 验证子串 s[left, right] 是否为回文串 function valid($s, $left, $right) { while ($left < $right) { if ($s[$left] != $s[$right]) return false; $left++; $right--; } return true; } //中心扩散法 function extendByCenter($s, $left, $right) { while ($left >= 0 && $right < strlen($s) && $s[$left] == $s[$right]) { if ($right - $left + 1 > $this->max) { $this->max = $right - $left + 1; $this->res = substr($s, $left, $right - $left + 1); } $left--; $right++; } } //动态规划:保存子问题的解来求解原问题的解 function dplongestPalindrome($s) { if (strlen($s) <= 1) return $s; $res = $s[0];//1个字符也是回文串 $max = 0; //2个字符的情况 if ($s[0] == $s[1]) { $res = substr($s, 0, 2); } for ($j = 2; $j < strlen($s); $j++) { $dp[$j][$j] = true;//1个字符肯定是回文串 for ($i = 0; $i < $j; $i++) { // aab3baa : $j - $i <= 2, 中间隔一个字母的情况也是回文串:b3b $dp[$i][$j] = $s[$i] == $s[$j] && ($j - $i <= 2 || $dp[$i + 1][$j - 1]); if ($dp[$i][$j] && $max < $j - $i + 1) { $max = $j - $i + 1; $res = substr($s, $i, $j - $i + 1); } } } return $res; }}
GO 代码实现
func longestPalindrome(s string) string { if s == "" { return "" } start, end := 0, 0 for i := 0; i < len(s); i++ { left1, right1 := expandCenter(s, i, i) left2, right2 := expandCenter(s, i, i+1) step := end - start if right1 - left1 > step { start, end = left1, right1 } if right2 - left2 > step { start, end = left2, right2 } } return s[start: end + 1]}func expandCenter(s string, left, right int) (int, int) { for ; left >= 0 && right < len(s) && s[left] == s[right]; left, right = left-1, right+1 {} return left + 1, right - 1}