目录
方法一:中心向两边扩散找最大回文子串,同时遍历所有点都作为中心点试一试。
重点:子函数的返回类型为vector型(这样就可以返回多个数了)
方法2:思想上从外向内扒开。如果一个串左右两侧相等那么该串是否是回文子串取决于扒开后的是不是回文串。
重点:复制字符串函数 string result=s.substr(begin,len); 将字符串“ s ”从 begin 下标开始连续复制 len 个给result
方法一:中心向两边扩散找最大回文子串,同时遍历所有点都作为中心点试一试。
class Solution {
public:
vector<int> result(int left,int right,string s)
{
int n=s.length();
while((right<n)&&(left>=0)&&(s[left]==s[right])){
left--;
right++;
}
int p[2]={left+1,right-1};
vector< int >result(p,p+2);
return result;
}
string longestPalindrome(string s) {
int n=s.length();
int start=0;
int end=0;
for(int i=0;i<n;i++){
vector< int >result1(2);
result1=result(i,i,s);int len1=result1[1]-result1[0]+1;//cout<<result1[0]<<" "<<result1[1]<<endl;
vector< int >result2(2);
result2=result(i,i+1,s);int len2=result2[1]-result2[0]+1;//cout<<result2[0]<<" "<<result2[1]<<endl;
if(len1>end-start+1){end=result1[1];start=result1[0];}
if(len2>end-start+1){end=result2[1];start=result2[0];}
}
return s.substr(start,end-start+1);
}
};
根据提示寻找回文子串可以从选定的点向两边扩散,
同时回文串的中心可能是一个“aba”也可能是两个“abba”。所以在遍历每个中心点时要对两种可能情况(中心是单或两个相同的双)都进行计算。
主函数里对所有点从左到右进行迭代选出以每个点作为中心或中心的一半时的最大长度并记录左右边界点。同时不断更新作为记录结果的最大长度和边界点。
子函数里因为要返回左右边界点两个数值,所以不能用以前的方式。
重点:子函数的返回类型为vector型(这样就可以返回多个数了)
在该题尝试过返回数组的指针,但是*p能返回,但是*(p+1)的结果不正确了,经过多次尝试后还是不知道咋调。
选择子函数的返回类型为vector型,使用方法与以前返回int或者char一样。
vector< 返回向量中每个元素的数据类型 >函数名(参数1类型 参数1名称,参数2类型 参数2名称,){
vector<返回向量中每个元素的数据类型>向量名(向量中元素个数);
············
return 向量名;
}
主函数里面直接赋值向量。向量名=函数名(参数1,参数2);
方法2:思想上从外向内扒开。如果一个串左右两侧相等那么该串是否是回文子串取决于扒开后的是不是回文串。
class Solution {
public:
string longestPalindrome(string s) {
int n=s.length();
int maxl=1;
int begin=0;
if(n<2){
return s;
}
vector<vector< int >>xi(n,vector<int>(n));
for(int i=0;i<n;i++){
xi[i][i]=true;
}//单字母结果都初始化为true
//从2个字母长度开始进行迭代
for(int l=2;l<=n;l++){
for(int i=0;i<n;i++){
int j=i+l-1;
if(j>=n){break;}
if(s[i]!=s[j]){xi[i][j]=false;}
else if(s[i]==s[j]&&j-i<3){xi[i][j]=true;}
else if(s[i]==s[j]&&j-i>=3){xi[i][j]=xi[i+1][j-1];}
//xi[i+1][j-1]是长度较短的已经先进行过迭代了所以可以直接赋值给别人
if(xi[i][j]&&l>maxl){maxl=l;begin=i;}
}
}
string result=s.substr(begin,maxl);
//str.substr(begin,len)为复制字符串函数,从begin位置开始连续复制len长度。
return result;
}
};
回文串的长度从1到n都有可能。所以首先遍历可能的回文串的长度。
对于每一个可能的回文串长度不同的起点都是有可能的,所以在内层遍历可能的起点(注意终点不要越界,越界就退出一层循环就行)
如果该起点对应的数值和”起点+长度“推出的终点对应的数值不相等,那么也不用算了,这一对起点终点对应的不成立。
如果相等,那么这对起点终点是否是回文串取决于左右各扒一层后的串是否是回文子串。(由于长度从小到大迭代,扒一层后的结果是已经计算出来了的)
如果判断了这对起点终点对应的起点终点是回文子串,那么迭代输出结果就行了。