给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba"也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
这道题就是很朴素的,从每位开始向两侧判断是否回文。
以示例2为例,由于没有一个中间位。所以将字符串中插入分隔符#,每两个字符间都加入一个分隔符,之后所有的可能都可以变成奇数长度的字符串。
这道题还有一个简化方法:“马拉车算法”,即假设一个大的回文内部,存在一个小的回文值,则小的回文值可以直接从对称值开始增加,减少了一部分的重复计算。
参考资料1:https://www.cnblogs.com/grandyang/p/4475985.html
参考资料2:(很喜欢里面提到的:学好写暴力,走遍天下都不怕)https://www.cnblogs.com/ZDHYXZ/p/7697777.html
从展开的字符串如何映射回原来的字符串呢?
0 1 2 3 4 5 6
对照映射的是
# 0 # 1 # 2 #
原字符串位置*2 + 1 = 新字符串位置
新字符串起始字符位置 = 中心位置 - 单侧最长距离
则原字符串起始字符位置 = ( 中心位置 - 单侧最长距离 - 1 )/ 2
由于不同的实现方法不同,以及max表示的含义不同,以及为了隔开首位的井号,因此我最终的实现是
s.substr((max_mid - max + 2)/2,max - 1);
本地测试可通过,但是测试点ababa,leetcode报错“terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr: __pos (which is 18446744073709551614) > this->size() (which is 5)”
报错信息中,第一个__pos的值是一段乱码。原来是while循环中当i-j<0的时候,会出现未知现象。
参考资料1中,使用了最初始位置添加¥的方法,规避了该问题。而我疏忽了这一点
得到的参数s是个string类型,由于我对string类型的具体语法不熟练,所以参考了他人博客。
参考资料3:(标准C++中的string类)https://www.cnblogs.com/aminxu/p/4686320.html
参考资料4:(string的遍历)https://blog.csdn.net/stpeace/article/details/50406627
完整代码:
#include<vector>
#include<ctype.h>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
string longestPalindrome(string s) {
if(s == ""){
return s;
}
string fold = "#";
int i,j,len,max,max_mid,tmp_mid,tmp_r;
for(i = 0; i < s.size(); i++){
fold += s[i];
fold += '#';
}
len = fold.size();
vector<int> value(len, 0); //此行学自参考资料1
max = 2;
max_mid = tmp_mid = tmp_r = 1;
for(i = 2; i < len; i++){
value[i] = (tmp_r > i)? min(value[tmp_mid *2 - i], tmp_r - i): 1;
j = value[i];
while(fold[i + j] == fold[i - j]){
j++;
}
value[i] = j;
if(i + j > tmp_r){
tmp_r = i + j;
tmp_mid = i;
}
if(j >= max){
max = j;
max_mid = i;
}
// cout << i << " " << fold[i] << endl;
// cout << max << " mid:" << max_mid << endl;
}
// cout << fold << endl;
// cout << max_mid - max + 2 << endl;
return s.substr((max_mid + 2 - max)/2,max - 1);
}
int main(){
string s = "a";
s = longestPalindrome(s);
cout << s << endl;
return 0;
}
网友评论