题目:https://leetcode-cn.com/problems/longest-palindromic-substring/
题目
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
解法
1. 中心扩展法
顾名思义,该方法的核心思路是,逐一检查字符串中可以构成中心的中间节点(具有如aba或者aa结构的即可视为一个中心节点)。
找到中心节点后,下一步就是确定回文字符串的left和right边界,对于aba结构来说,显然left和right边界即为a对应数组中的位置,而对于aa结构而言,先可以确定一个左边界,由于暂时无法确定后面是否存在多个a(如babaaaab,回文部分是baaaab,有四个a组成),故右边界仍需往下扫描,直到扫描到不是a的部分位置。
找到左右边界后,开始左右同时向两边扩展,若两边界上的元素一致,则继续往下探索,否则停止判断,记录该回文串的长度及下标。
| 
					 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54  | 
						class Solution { public:     string longestPalindrome(string s) {         int left;         int right;         int leftSure=0;         int rightSure=0;         if(s.length()<2){    //如果字符串长度小于2,则直接返回,leetcode有一个测试用例是空字符串             return s;         }         for(int i=0;i<s.length()-1;i++){  //对字符串内容进行逐个扫描             if(i==s.length()-2){          //如果当前节点为字符串的倒数第二个字符,则只检测s[i]与s[i+1],防止后续s[i+2]越界                 if(s[i]==s[i+1]){                     left = i;                     right = i+1;                     if((right-left)>(rightSure-leftSure)){                         rightSure = right;                         leftSure = left;                     }                 }               }             else if(s[i]==s[i+1]||s[i]==s[i+2]){  //检测两种模式类型                 if(s[i]==s[i+1]){                     left = i;                     right = s.length()-1;                     for(int j=i+2 ;j<s.length();j++){                         if(s[j]!=s[left]){                             right = j-1;                             break;                         }                     }                 }else{                     left = right = i+1;                 }                 //get finish left and right                 while(left>=1&&right<s.length()-1){  //开始向两边扩展                     if(s[left-1]==s[right+1]){                         left--;                         right++;                     }else{                         break;                     }                 }                 if((right-left)>(rightSure-leftSure)){   //求最大值                     rightSure = right;                     leftSure = left;                 }             }            }         return s.substr(leftSure,rightSure-leftSure+1);   //用了substr方法,进行截取字符串,其中第一个参数为截取开始的下标,第二个参数为截取的长度     } };  | 
					
2. 暴力法
选出所有子字符串可能的开始和结束位置,并检验它是不是回文。
3. 动态规划
动态规划的算法核心思想是把多阶段问题转换为单阶段问题
在本题中,可以将字符串回文部分的搜索视为从小到大的过程,即状态方程P(i , j) = ( P(i+1,j-1) && 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 31 32 33  | 
						class Solution { public:     string longestPalindrome(string s) {         //动态规划解法         int len = s.length();         int max = 1;         int start = 0;         vector<vector<int>> dp(len,vector<int>(len));         if(len<2){             return s;         }         //赋初值         for(int i=0;i<len-1;i++){             dp[i][i] = 1;             if(s[i]==s[i+1]){                 dp[i][i+1] = 1;                 max = 2;                 start = i;             }         }         //动态规划         for(int i=3;i<=len;i++){             for(int j=0;j<len-i+1;j++){                 if(s[j]==s[j+i-1]&&dp[j+1][j+i-2]==1){                     dp[j][j+i-1]=1;                     max = i;                     start = j;                 }             }         }         return s.substr(start,max);      } };  | 
					
4. 马拉车算法
等待更新(https://leetcode-cn.com/problems/longest-palindromic-substring/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-bao-gu/)