leetcode#5最长回文数C++
一.思路一:中心扩散
对每一个字符,检测它与它旁边的数是否为回文数,如果是,那么再扩展它 的长度检查,分奇偶情况讨论,得到以该字符为中心最长的回文数。在遍历过程中用max[2]储存该目前最长的回文数位置和长度。这样算法时间复杂度为O(n^2)。
1.1代码实现
1.1.1# 新工具
string s;
s.substr(int i,int j);
用于截取string,返回s[i]开始j个字符。
string+=s[i];
int max(int a,int b)
返回a,b中大的一个
1.1.2# 不甘放弃
class Solution {
public:
string longestPalindrome(string s) {
int len=s.size();
if(len==0||len==1)
return s;
int start=0;//记录最大回文子串起始位置
int end=0;//记录最大回文子串终止位置
int mlen=0;//记录以s【i】为中心最大回文子串的长度
for(int i=0;i<len;i++)
{
int len1=expendaroundcenter(s,i,i);//一个元素为中心
int len2=expendaroundcenter(s,i,i+1);//两个元素为中心
mlen=max(max(len1,len2),mlen);//记录以i为中心的最大回文数
if(mlen>end-start+1)//记录最大的回文数
{
start=i-(mlen-1)/2;
end=i+mlen/2;
}
/*if(i>len/2&&mlen/2>len-i)
break;(精简步骤edition2)*/
}
return s.substr(start,mlen);
//该函数的意思是获取从start开始长度为mlen长度的字符串
}
private:
int expendaroundcenter(string &s,int left,int right)
//!!!!这里&s,大幅提升效率!!!!!
//计算以left和right为中心的回文串长度
{
int L=left;
int R=right;
while(L>=0 && R<s.length() && s[R]==s[L])//防止越界我
{
L--;
R++;
}
return R-L-1;
}
};
```/*
改编自chenlele
链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-c-by-gpe3dbjds1/
来源:力扣(LeetCode)*/
执行用时:16 ms, 在所有 C++ 提交中击败了94.83%的用户
内存消耗:6.9 MB, 在所有 C++ 提交中击败了99.68%的用户
思考
可以根据已有最长回文串长度mlen与i的位置,进一步缩小程序。
edition 2
可以看见用时缩短了一倍,但内存增加了0.1mb
1.2简化:Manacher
给字符串插#
字符+### | 总长 |
---|---|
偶数+奇数 | 奇数 |
“abcd” | “#a#b#c#d#” |
奇数+偶数 | 奇数 |
“abc” | “#a#b#c#” |
1.2.1实现方法
用一个辅助string存储新字符串,得到辅助最长回文串以[i]为中心,扩散了mlen步,长2*mlen+1。
映射到原字符串以i/2为中心扩散了mlen/2步。
那么这个字符串覆盖了2 *(mlen/2)个间隔
原 | 0 | 1 | 2 | 3 | ||||
---|---|---|---|---|---|---|---|---|
a | b | c | d | |||||
辅助 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
输出:
start = (i - mlen) / 2;
return s.substr(start, mlen);
1.2.2代码实现
int centerSpread(string &s, int center) {
int len = s.size();
int i = center - 1;
int j = center + 1;
int step = 0;
while (i >= 0 && j < len && s[i] == s[j]) {
i--;
j++;
step++;
}
return step;
}
public:
string longestPalindrome(string &s) {
int size = s.size();
if (size < 2) {
return s;
}
string str = "#";
for (int i = 0; i < s.size(); ++i) {
str += s[i];
str += "#";
}
int sSize = 2 * size + 1;
int maxLen = 1;
int start = 0;
for (int i = 0; i < sSize; i++) {
int curLen = centerSpread(str, i);
if (curLen > maxLen) {
maxLen = curLen;
start = (i - maxLen) / 2;
}
}
return s.substr(start, maxLen);
}
};
作者:liweiwei1419
链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/
来源:力扣(LeetCode)