Leetcode 5 最长回文串
思路
1.暴力解法
可以判断每个字符串是否是回文串,但由于截取会慢,可以写一个子函数用来判断一个字符串是不是回文(从一个字符串两边开始判断,一旦不相等直接返回false,否则指针向中间同时移一位)
代码
bool valid(string s&,int l,int r){
while(l<r){
if(s[l]==s[r]){
l++;
r--;
}else
return false;
}
return true;
}
string longrev(string s){
int maxlen=0,begin=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(valid(s,i,j)&&j-i+1>1){
maxlen=max(maxlen,j-i+1);
begin=i;
}
}
}
return s.substr(i,maxlen);
}
这种方法在LeetCode上会超时,所以只是写出暴力写法
2.动态规划!!!
最长回文串的动态规划怎么思考呢?
- 首先,从特例开始,如果这个字符串只有一个字符,也就是 i==j 的情况,就是回文串
- 如果字符串长度为2的情况取决于这两个字符是否相等 也就是 s[i]==s[j] 是否成立
- 字符串大于2的情况:满足回文串的条件是两个,一个是当前 s[i]==s[j],一个是这个字符串的 i+1,j-1部分也是回文串
那么综上所示可以写出动态规划的代码了
string longrev(string s){
if(s.size()<2) return s;//只有一个字符必是最大回文子串
int maxlen=1,start=0;//因为题目说了字符串肯定大于1,那么最大回文子串长度必定大于等于1
for(int j=0;j<s.size();j++){
for(int i=j;i>=0;i--){
if(i==j){
dp[i][j]=1;//上面分析的第一点
}else{
if(j-i+1==2){//第二点
dp[i][j]=s[i]==s[j];
}else{//第三点
dp[i][j]=dp[i+1][j-1]&&s[i]==s[j];
}
}
//更新最大值
if(j-i+1>maxlen&&dp[i][j]){
maxlen=max(maxlen,j-i+1);
start=i;//保存最大回文子串的起始值
}
}
}
return s.substr(start,maxlen);
}