manacher算法处理最长的回文子串(二)

在上篇《manacher算法处理最长的回文子串(一)》解释了manacher算法的原理,接着给该算法,该程序在leetcode的最长回文子串中通过。首先manacher算法维护3个变量。一个名为radius[i]的数组,表示以i为中心轴承的回文子串的半径,如abcdcba中,字符d的下标为4,则他的radius[4]=3,下标的为0的a的半径为radius[0]=0,即中心轴不考虑其中。一个idx表示上一次以idx为中心轴的回文。如果当以i为中心的回文在以idx为中心的回文内。则idx不更新,否则处理完radius[i]后,需要把idx更新为i。最后一个rad维护idx能够包含最大的范围的下一个字符下标,事实上当i+radius[i]到到达rad时就需要更新idx。

代码:

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         int n=s.size();
 5         string str(2*n+1,‘0‘);
 6         bool flag=1;
 7         int j=0;
 8         int maxIdx=0;
 9         for(int i=0;i<2*n+1;i++){
10            if(flag){
11                str[i]=‘#‘;
12                flag=false;
13            }else{
14                str[i]=s[j++];
15                flag=true;
16            }
17         }
18         vector<int> radius(2*n+1,0);
19         int idx=0;
20         int rad=1;
21         for(int i=1;i<2*n+1;i++){
22             if(i>=rad){
23                 forceExtend(str,radius,idx,rad,i);
24                 maxIdx=(radius[i]>radius[maxIdx]?i:maxIdx);
25             }else if(i<rad){
26                 int j=2*idx-i;
27                 int idx_radius=idx-radius[idx];
28                 int j_radius=j-radius[j];
29                 if(j_radius>idx_radius){
30                     radius[i]=radius[j];
31                 }
32                 else if(j_radius<idx_radius){
33                     radius[i]=idx+radius[idx]-i;
34                 }else{
35                     radius[i]=idx+radius[idx]-i;
36                     int count=1;
37                     while((i+radius[i]+count)<=str.size()&&(i-radius[i]-count)>=0&&str[i+radius[i]+count]==str[i-radius[i]-count])
38                         count++;
39                     radius[i]+=(count-1);
40                     if(i+radius[i]>=rad){
41                         idx=i;
42                         rad=i+count;
43                     }
44                 }
45                 maxIdx=(radius[i]>radius[maxIdx]?i:maxIdx);
46             }
47
48         }
49         string ret=getMaxSubString(str,maxIdx,radius[maxIdx]);
50         return ret;
51     }
52     void forceExtend(const string& str, vector<int>& radius,int &idx,int &rad,const int k){
53         int count=1;
54         while((k-count)>=0&&(k+count)<str.size()&&str[k-count]==str[k+count]){
55             count++;
56         }
57         radius[k]=count-1;
58         if(k+radius[k]>=rad){
59             idx=k;
60             rad=k+count;
61         }
62     }
63     string getMaxSubString(const string &str,const int k,const int r){
64         string ret(r,‘0‘);
65         int j=0;
66         for(int i=k-r+1;i<=k+r;i+=2){
67             ret[j++]=str[i];
68         }
69         return ret;
70     }
71
72 };

时间: 2024-11-03 13:03:06

manacher算法处理最长的回文子串(二)的相关文章

manacher算法处理最长的回文子串(一)

引言 相信大家都玩过折叠纸张,如果把回文串相当于折叠一个A4纸,比如ABCDDCBA就是沿着中轴线(D与D之间)对折重合,那么这个就是一个回文串.或者是ABCDEDCBA的中轴线就是E,那么沿着中轴线对折也是重合的,所以这个字符串也是一个回文串. 判断一个字符串中的最长回文子串,我们可以对每个字符的两边进行比较,还是如何ABCDEDCBA,在A,B,C,D分别为中心轴向两边扩展的回文子串长度都是1,就是它自己本身,当扫描以E为中心轴时,那么这个回文的最长子串时9,也就是这个字符串本身.然而当用相

hihoCoder #1032 : 最长回文子串 [ Manacher算法--O(n)回文子串算法 ]

传送门 #1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?” 小Ho奇怪的问道:“什么叫做最长回文子串呢?” 小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串

hdu 3068 Manacher算法 O(n)回文子串算法

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3068 关于算法的教程  推荐这个:http://blog.csdn.net/ggggiqnypgjg/article/details/6645824    注意:我推荐的这篇博客里说的那个代码有bug,我觉得没问题,而是博主在用的时候写错了,博主举得反例我都过了 而且hdu 3068也过了 最开始是用的后缀数组,2000ms+ 果断超时............... 看过一遍很快就学会这个算法了:然后A

LeetCode:5_Longest Palindromic Substring | 最长的回文子串 | Medium

题目: Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 解题思路:1.简单思路:暴力破解法,时间复杂度O(n^3),肯定通不过. 2.动态规划法:(一般含“最XX”等优化词义的题意味着都可以动态规划

算法学习笔记——判断最小回文子串

利用C语言实现的最长回文子串算法 1 # include<stdio.h> 2 # include<string.h> 3 # include<ctype.h> 4 5 # define MAXN 5000 + 10 6 char buf[MAXN], s[MAXN]; //buf输入字符串, s去掉标点空格并转为大写的预处理字符串 7 int p[MAXN]; // p用于记录处理后字符串s中,每个字符在原字符串buf中的序号 8 int main(){ 9 10 i

找出字符串中的最长的回文子串

1 class Solution { 2 public: 3 string longestPalindrome(string s) { 4 int maxLoc=0; 5 int maxNum=1; 6 const int stringSize=s.size(); 7 if(stringSize==1){ 8 return s; 9 } 10 11 for(int i=1; i!= 2*stringSize-1-1;++i){ 12 int a, b; 13 int num=1; 14 if(i

5. Longest Palindromic Substring 最长的回文子串

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Example: Input: "babad" Output: "bab" Note: "aba" is also a valid answer. Example: Input: "cbbd" Ou

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

public String longestPalindrome(String s) { if(s == null||s.length()==0){ return s; } String res = ""; int max=0; boolean[][] dp = new boolean[s.length()][s.length()]; //res=s.substring(0, 1); for(int j = 0;j < s.length();j++){ for(int i=0;i&

最长回文子串之Manacher算法

以Hihocoder 1032为例. manacher算法: 设一个数组p,p[i]表示以第i个字符为中心的最大半径,最大的p[i]就是最长的回文子串了. 不过这样要用两个循环,时间复杂度是(n*n). 1 int solve(){ 2 int len = strlen(str), ans = 0; 3 for(int i = 0; i < len; i ++){ 4 for(int j = 0; i-j>=0 && i+j < len; j++){ 5 if(str[i