题目地址 
https://leetcode.cn/problems/longest-palindromic-substring/ 
 
题目描述 1 2 3 4 5 6 7 8 9 10 11 12 13 给你一个字符串 s,找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。 示例 1: 输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。 示例 2: 输入:s = "cbbd" 输出:"bb" 
 
解法一 中心扩散法 由简入繁 先看一个最简单的字符串,比如’aabaaabaa’;
第一步,i=0,这时候 res=’a’,如果回文子串长度是奇数,左边无值,右边有值,这时候最长回文子串是’a’,如果回文子串长度是偶数,res=’aa’这时候最长回文子串是’aa’; 
第二步,i=1,这时候 res=’a’,如果回文子串长度是奇数,左边有一个值’a’,右边的值为’b’,这时候当前 i 位置最长回文子串是’a’,如果回文子串长度是偶数,res=’aa’或者 res=’ab’这时候最长回文子串是’aa’; 
第三步,i=2,这时候 res=’b’,如果回文子串长度是奇数,左边第一个值’a’,右边第一个值为’a’,res=’aba’,左边第二个值’a’,右边第二个值’a’,res=’aabaa’,这时候最长回文子串还是’aabaa’,如果回文子串长度是偶数,最长的长度为 1; 
第四步,i=3,…这时候最长回文子串还是第三步的’aabaa’; 
第五步,i=4,这时候 res=’a’ … 这时候最长回文子串还是第三步的’aabaaabaa’; …. 
 
思路 
如果 s 的长度是 1 或者 0 的时候,s 的最长回文子串就是它本身,例如’a’,直接返回 s。 
 
 
 
1 2 3 if  (s.length  < 2 ) {  return  s } 
 
遍历整个 s 例:s 字符串 ‘acaca’,遍历字符串,区分 i 为奇数和偶数的情况; 在 s 的范围内(所以需要 m>=0 ,n<s.length),从中心往两边去遍历,如果s[m] == s[n],如果如果此时回文字符串的长度大于之前最大长度则取 n-m-1 
 
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 const  longestPalindrome = function  (s ) {  if  (s.length  < 2 ) {     return  s   }   let  res = ''    for  (let  i = 0 ; i < s.length ; i++) {          helper (i, i)          helper (i, i + 1 )   }   function  helper (m, n ) {     while  (m >= 0  && n < s.length  && s[m] == s[n]) {       m--       n++     }               if  (n - m - 1  > res.length ) {              res = s.slice (m + 1 , n)     }   }   return  res } 
 
解法二 动态规划 思路 
状态定义 dp[i,j]:字符串 s 从索引 i 到 j 的子串是否是回文串 
 
true: s[i,j] 是回文串 
false:s[i,j] 不是回文串 
 
转移方程 dp[i][j] = dp[i+1][j-1] && s[i] == s[j] 
 
s[i] == s[j]:说明当前中心可以继续扩张,进而有可能扩大回文串的长度 
dp[i+1][j-1]:true
说明 s[i,j]的**子串 s[i+1][j-1]**也是回文串 
说明,i 是从最大值开始遍历的,j 是从最小值开始遍历的 
 
 
特殊情况
j===i:s[i]和是[j]值是同一个值 
j - i === 1:表示 s[i]和是[j]为相邻值,则需要是 s[i]===s[j] 
 
 
 
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 const  longestPalindrome = function  (s ) {  if  (!s || s.length  < 2 ) return  s   let  res = s[0 ]   const  dp = []      for  (let  i = s.length  - 1 ; i >= 0 ; i--) {     dp[i] = []     for  (let  j = i; j < s.length ; j++) {       if  (j - i === 0 ) dp[i][j] = true                else  if  (j - i === 1  && s[i] === s[j])         dp[i][           j         ] = true                else  if  (s[i] === s[j] && dp[i + 1 ][j - 1 ]) {                           dp[i][j] = true        }       if  (dp[i][j] && j - i + 1  > res.length ) {                  res = s.slice (i, j + 1 )       }     }   }   return  res }