版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xianqianshi3004/article/details/81120023
要求找出最长回文字符串,一开始采用比较笨的方法,两个for循环遍历然后判断每一个字串是不是回文时间复杂度是O(n3)
class Solution {
public:
string longestPalindrome(string s) {
int maxlen=0;
string res="";
for(int i=0;i<s.size();i++){
for(int j=s.size()-1;j>=i;j--){
if(s[i]!=s[j])
continue;
else{
int m=i;
int n=j;
while(n>=m){
if(s[n]==s[m])
n--,m++;
else
break;
}
if(m>n){
if(maxlen<j-i+1){
maxlen=j-i+1;
res=s.substr(i,maxlen);
}
}
}
}
}
return res;
}
};
下图中这种方法是针对一个元素然后往两侧延伸(这分为两种情况:奇偶情况),计算最大的长度。 时间复杂度O(N2)
转自--------http://www.cnblogs.com/grandyang/p/4464476.html
class Solution {
public:
string longestPalindrome(string s) {
int len=0,left=0,right=0;
int start=0;
for(int i=0;i<s.size()-1;i++){//对于每一个元素我们分两种情况来检验,一是偶数情况下,而是奇数情况下;
if(s[i]==s[i+1]){
left=i;
right=i+1;
searchPalindrome(left,right,s,start,len);
}
left=right=i;
searchPalindrome(left,right,s,start,len);
}
if(len==0) len=s.size();
return s.substr(start,len);
}
void searchPalindrome(int left,int right,string s,int &start,int &len){
int curlen=0,step=1;
while(left-step>=0&&right+step<s.size()){
if(s[left-step]!=s[right+step])
break;
else
step++;
}
curlen=right+step-1-(left-step+1)+1;
if(curlen>len){
start=left-step+1;
len=curlen;
}
}
};
接下来这种方法是动态规划:dp[j][i]代表j和i之间的字符串是不是回文,若i==j,dp[j][i]==1,若s[i]==s[j]情况下,若i=j+1则dp[j][i]==1,若i>j+1,dp[j][i]=dp[j+1][i-1]; 时间复杂度是O(N2)
###根据动态规划公式,我们可知想要求dp[j][i]需要知道dp[j+1][i-1],那怎么保证在判断dp[j][i]
之前dp[j+1][i-1]呢?所以在内层循环时范围是0-i而不是i-s.size();
string longestPalindrome(string s) {
int dp[s.size()][s.size()]={0},left=0,right=0,len=0;
for(int i=0;i<s.size();i++){
for(int j=0;j<i;j++){
dp[j][i]=(s[i]==s[j]&&(i - j < 2 || dp[j + 1][i - 1]));
if (dp[j][i] && len < i - j + 1) {
len = i - j + 1;
left = j;
right = i;
}
}
dp[i][i]=1;###注意到j的范围是[0,i),所以要这里要修改dp[i][i]的值。
}
return s.substr(left, right - left + 1);###至于这个地方为什么不用(left,len)是因为如果只有一个字符的时候len=0,所以返回为空,造成不结果不对,当然也可以在开始判断s的长度。
}