题意

WeChatc94bc4f17d091b8d1c913775734b24d0.png

解题思路:

  • 动态规划三部曲:
  • 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 代码实现

  1. class Solution {
  2. public $res = '';
  3. public $max = 0;
  4. /**
  5. * @param String $s
  6. * @return String
  7. */
  8. function longestPalindrome($s) {
  9. if (strlen($s) <= 1) return $s;
  10. for ($i = 0; $i < strlen($s); $i++) {
  11. $this->extendByCenter($s, $i, $i);//aba
  12. $this->extendByCenter($s, $i, $i + 1);//abba
  13. }
  14. return $this->res;
  15. }
  16. //暴力法
  17. function longestPalindrome1($s) {
  18. $len = strlen($s);
  19. if ($len < 2) return $s;
  20. $maxLen = 1;
  21. $res = substr($s, 0, 1);
  22. for ($i = 0; $i < $len - 1; $i++) {
  23. for ($j = $i + 1; $j < $len; $j++) {
  24. if ($j - $i + 1 > $maxLen && $this->valid($s, $i, $j)) {
  25. $maxLen = $j - $i + 1;
  26. $res = substr($s, $i, $j - $i + 1);
  27. }
  28. }
  29. }
  30. return $res;
  31. }
  32. // 验证子串 s[left, right] 是否为回文串
  33. function valid($s, $left, $right) {
  34. while ($left < $right) {
  35. if ($s[$left] != $s[$right]) return false;
  36. $left++;
  37. $right--;
  38. }
  39. return true;
  40. }
  41. //中心扩散法
  42. function extendByCenter($s, $left, $right) {
  43. while ($left >= 0 && $right < strlen($s) && $s[$left] == $s[$right]) {
  44. if ($right - $left + 1 > $this->max) {
  45. $this->max = $right - $left + 1;
  46. $this->res = substr($s, $left, $right - $left + 1);
  47. }
  48. $left--;
  49. $right++;
  50. }
  51. }
  52. //动态规划:保存子问题的解来求解原问题的解
  53. function dplongestPalindrome($s) {
  54. if (strlen($s) <= 1) return $s;
  55. $res = $s[0];//1个字符也是回文串
  56. $max = 0;
  57. //2个字符的情况
  58. if ($s[0] == $s[1]) {
  59. $res = substr($s, 0, 2);
  60. }
  61. for ($j = 2; $j < strlen($s); $j++) {
  62. $dp[$j][$j] = true;//1个字符肯定是回文串
  63. for ($i = 0; $i < $j; $i++) {
  64. // aab3baa : $j - $i <= 2, 中间隔一个字母的情况也是回文串:b3b
  65. $dp[$i][$j] = $s[$i] == $s[$j] && ($j - $i <= 2 || $dp[$i + 1][$j - 1]);
  66. if ($dp[$i][$j] && $max < $j - $i + 1) {
  67. $max = $j - $i + 1;
  68. $res = substr($s, $i, $j - $i + 1);
  69. }
  70. }
  71. }
  72. return $res;
  73. }
  74. }

GO 代码实现

  1. func longestPalindrome(s string) string {
  2. if s == "" {
  3. return ""
  4. }
  5. start, end := 0, 0
  6. for i := 0; i < len(s); i++ {
  7. left1, right1 := expandCenter(s, i, i)
  8. left2, right2 := expandCenter(s, i, i+1)
  9. step := end - start
  10. if right1 - left1 > step {
  11. start, end = left1, right1
  12. }
  13. if right2 - left2 > step {
  14. start, end = left2, right2
  15. }
  16. }
  17. return s[start: end + 1]
  18. }
  19. func expandCenter(s string, left, right int) (int, int) {
  20. for ; left >= 0 && right < len(s) && s[left] == s[right]; left, right = left-1, right+1 {}
  21. return left + 1, right - 1
  22. }