华为OJ-最长回文子串-Manacher算法
2017-08-01 17:40 mengmz 阅读(410) 评论(0) 编辑 收藏 举报题目描述
给定一个字符串str,返回str中最长回文子串的长度。
示例
输入
ABBA
输出
4
求解方法
采用经典的Manacher算法,时间复杂度为\(log{N}\)。
代码及注释如下:
#include <iostream>
#include <vector>
using namespace std;
int manacher(const string & str){
if(str.size() == 0) return 0;
string mana_str;
// 插入间隔符#
for(int i = 0; i < str.size(); ++i){
mana_str +='#';
mana_str += str[i];
}
mana_str += '#';
int index = -1; //记录pR所对应的回文子串对称轴的位置
int pR = -1; //当前访问到的所有回文子串中,所能触及到的最大位置的下一个
int max_len = 0; //记录最长回文子串长度
vector<int> pArr(mana_str.size()); //记录以i为对称轴的最长回文子串的半径
for(int i = 0; i < mana_str.size(); ++i){
//分两种情况,i在pR的左侧或右侧
pArr[i] = pR > i? min(pArr[2 * index - i], pR - i) : 1;
while(i + pArr[i] < mana_str.size() && i - pArr[i] > -1){
//以i为中心,在上步的基础上扩展,直至到达边界或者字符不相等
if( mana_str[i + pArr[i]] == mana_str[i - pArr[i]])
pArr[i] ++;
else
break;
}
// 更新pR和index
if(i + pArr[i] > pR){
pR = i + pArr[i];
index = i;
}
max_len = max(max_len, pArr[i]);
}
//对以i为中心的回文子串,其在原串中的长度为pArr[i] - 1
return max_len - 1;
}
int main() {
ios::sync_with_stdio(false);
string password;
while(cin >> password){
cout << manacher(password)<<endl;
}
return 0;
}
- 理解代码中变量的含义至关重要;
- 对应的题目有字符串运用-密码截取;
- 算法详细介绍参见回文子串算法