给你一个字符串 s
,找到 s
中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd" 输出:"bb"
提示:
1 <= s.length <= 1000
s
仅由数字和英文字母组成
思路:DP
dp[i][j]:第i个到第j个字符的字符串是否是回文串。规定dp[i][j]为1表示是,0表是否。
核心思想:如果dp[i][j]是回文串那么去头去尾的字符串也是回文串,即dp[i+1][j-1]一定是回文串,
故状态转移方程为:dp[i][j]=dp[i+1][j-1]&&(s[i]==s[j])bool相与
边界条件:dp[i][i]=1;dp[i][i+1]两种情况,s[i]是否等于s[i+1]判断
结果:dp[i][j]中j-i+1(回文数长度)的最大值对应的字符串
#include <bits/stdc++.h> using namespace std; class Solution { public: bool is(char s1,char s2) { if(s1==s2) {return true;} else{ return false; } } string longestPalindrome(string s) { int n=s.size(); vector<vector<bool>> dp(n, vector<bool>(n, false)); //先设定边界条件 for(int i=0;i<n;i++) { dp[i][i]=true; } for(int i=0;i<n-1;i++) { if(s[i]==s[i+1]) { dp[i][i+1]=true; } } //输入:aaaaa,输出aaaa;分析原因:d[0][4]=dp[1][3]..但dp[1][3]未确定,dp[1][3]由dp[2][2]确定因为是dp[i+1][j-1]所以i应该倒着找 /*for(int i=0;i<n-2;i++)错 { for(int j=i+2;j<n;j++) { dp[i][j]=dp[i+1][j-1]&&Solution::is(s[i],s[j]); } }*/ //正确dp顺序 for(int i=n-3;i>=0;i--) { for(int j=i+2;j<n;j++) { dp[i][j]=dp[i+1][j-1]&&Solution::is(s[i],s[j]); } } int maxl=0; int maxi=0; int maxj=0; for(int i=0;i<n;i++) { for(int j=i;j<n;j++) { if(dp[i][j]==true) { if(j-i+1>maxl) { maxl=j-i+1; maxi=i; maxj=j; } } } } return s.substr(maxi,maxl); } };