主要学习自:http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html

问题描述:回文字符串就是左右对称的字符串,如:"abba",而最长回文子串则是字符串长度最长的回文子字符串,如"abbaca"的最长回文子串为"abba"。

常规解法:显而易见采用嵌套循环的方式可以“暴力”结算出答案,其时间复杂度为O(n^2),而Manacher算法是一种更加省时的算法,其时间复杂度为O(n).

主要思路:

首先使用#(或其他什么符号)填充字符串,并声明一个数组来记录以字符串的每一个字符作为中心,回文字符的半径,使之成为这个样子:

str = # a # b # a # c # a # c # a # b # c # a # c #

arr = 0 1 0 3 0 1 0 3  0 7 0 3 0 1 0 1 0 1 0  3 0 1 0

由此我们可以看出,添加#的作用在于使得字符串无论是奇数长度还是偶数长度,在经过处理后都可以统计以每个字符为中心的回文半径,而偶数长度的回文无法统计这个,如:“abba”

计算出arr后,很容易得到最大回文子串的长度为7,为"bacacab"。

所以这个算法的关键在于计算arr,通过观察我们发现,arr中的数值其实也是对称的:

比如上述例子,以T[11]作为对称中心(回文半径为9),要求T[13]处的回文半径时,可根据其相对于T[11]的对称T[9]来计算,显然arr[13]=arr[9]。可以根据这个例子计算arr[i]=arr[i'].

但是这一方法并不是总是适用的,如:

当i=15时,由于arr[i']>R-i,所以arr[15]不一定等于与之对称的arr[7],如本例中arr[15]=5.因此我们得到以下规律:

if arr[ i’ ] ≤ R – i,
then arr[ i ] ← arr[ i’ ]
else P[ i ] ≥ R – i.

知道了如何计算回文半径,如何确定回文中心呢(即图中的C)?

采用的方式为i+arr[i]>R,则将C替换为i ,R替换为i+arr[i]

直接贴代码:

  1. string preProcess(string str)
  2. {
  3. //$是开头标识,string的结尾标识为\0
  4. string encoded = "$";
  5. int strlen = str.length();
  6. //加#的目的在于使得偶数位的回文字串更加容易辨别,如:"1221",在计算回文长度数组时,不好计算,但$1#2#2#1\0的回文长度(半径)数组为[0,0,0,1,3,1,0,0,0]
  7. for (int i = ; i < strlen; i++)
  8. {
  9. encoded += "#" + str.substr(i,);
  10. }
  11. encoded += "#";
  12. return encoded;
  13. }
  14.  
  15. string longestPalindrome(string str)
  16. {
  17. string temp = preProcess(str);
  18. //回文子串的中心
  19. int palindrome_center = ;
  20. //回文子串的右边界
  21. int right_border = ;
  22. int strlen = temp.length();
  23. //用来存储以该点为中心的回文字符串的半径长度,注意这里是半径长度,因为字符串是经过处理的,包含了#
  24. int * plength_array = new int[strlen];
  25. //i相对于center的对称处
  26. int mirror_i = ;
  27. //循环从1开始因为开头为标示符“$”
  28. for (int i = ; i < strlen; i++)
  29. {
  30. //i相对于回文中心的对称处
  31. mirror_i = * palindrome_center - i;
  32. if (mirror_i>&& right_border > i)//i在回文字符子串内
  33. {
  34. //若范围没有超过右边界,则回文数对称
  35. if (right_border - i > plength_array[mirror_i])
  36. plength_array[i] = plength_array[mirror_i];
  37. else
  38. plength_array[i] = right_border - i;//*先取一个最小值
  39. }
  40. else
  41. plength_array[i] = ;
  42. //针对上面*处先取一个最小值的情况
  43. while (temp[i + + plength_array[i]] == temp[i - - plength_array[i]])
  44. plength_array[i]++;
  45. //如果回文字串的长度超过了现有的右边界,则确立新的中心和右边界
  46. if (i + plength_array[i] > right_border)
  47. {
  48. palindrome_center = i;
  49. right_border = i + plength_array[i];
  50. }
  51. }
  52. //寻找plength_array中的最大元素
  53. int maxlen = ;
  54. //最长回文的中心
  55. int maxlen_center = ;
  56. for (int j = ; j < strlen; j++)
  57. {
  58. if (plength_array[j]>maxlen)
  59. {
  60. maxlen = plength_array[j];
  61. maxlen_center = j;
  62. }
  63. }
  64. delete[] plength_array;
  65. return str.substr((maxlen_center--maxlen)/,maxlen);
  66. }

求最长回文子串:Manacher算法的更多相关文章

  1. 求最长回文子串——Manacher算法

    回文串包括奇数长的和偶数长的,一般求的时候都要分情况讨论,这个算法做了个简单的处理把奇偶情况统一了.算法的基本思路是这样的,把原串每个字符中间用一个串中没出现过的字符分隔开来(统一奇偶),用一个数组p ...

  2. 九度OJ 1528 最长回文子串 -- Manacher算法

    题目地址:http://ac.jobdu.com/problem.php?pid=1528 题目描述: 回文串就是一个正读和反读都一样的字符串,比如"level"或者"n ...

  3. lintcode最长回文子串(Manacher算法)

    题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...

  4. 最长回文子串—Manacher 算法 及 python实现

    最长回文子串问题:给定一个字符串,求它的最长回文子串长度.如果一个字符串正着读和反着读是一样的,那它就是回文串.   给定一个字符串,求它最长的回文子串长度,例如输入字符串'35534321',它的最 ...

  5. 51nod1089 最长回文子串 manacher算法

    0. 问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字符串正着读和反着读是一样的,那它就是回文串.下面是一些回文串的实例: 12321 a aba abba aaaa ...

  6. hihocoder #1032 : 最长回文子串 Manacher算法

    题目链接: https://hihocoder.com/problemset/problem/1032?sid=868170 最长回文子串 时间限制:1000ms内存限制:64MB 问题描述 小Hi和 ...

  7. 5. Longest Palindromic Substring(最长回文子串 manacher 算法/ DP动态规划)

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...

  8. HiHo 1032 最长回文子串 (Manacher算法求解)

    /** * 求解最长回文字串,Manacher算法o(n)求解最长回文子串问题 **/ #include<cstdio> #include<cstdlib> #include& ...

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

    传送门 #1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相 ...

  10. 最长回文子串Manacher算法模板

    Manacher算法能够在O(N)的时间复杂度内得到一个字符串以任意位置为中心的回文子串.其算法的基本原理就是利用已知回文串的左半部分来推导右半部分. 首先,在字符串s中,用rad[i]表示第i个字符 ...

随机推荐

  1. 把 Mac 上的 bash 换成 zsh

      本人补充:mac版git下载地址:http://code.google.com/p/git-osx-installer/downloads/list?can=3&q=&sort=- ...

  2. asp.net 一句话搞定分页

    rows 是客户端传过来的行数,page是页码,传参就需要就两个参数就行,sql语句中_row 和_page 自己声明的局部变量,值还是相应的row 和page ,为了运算而已. 用数据库类获得它的D ...

  3. 推荐6款常用的Java开源报表制作工具

    JasperReports是一个基于Java的开源报表工具,它可以在Java环境下像其它IDE报表工具一样来制作报表.JasperReports 支持PDF.HTML.XLS.CSV和XML文件输出格 ...

  4. O2O、C2C、B2B、B2C的区别

    一.O2O.C2C.B2B.B2C的区别在哪里? o2o 是 online to offline 分为四种运营模式 1.online to offline 是线上交易到线下消费体验 2.offline ...

  5. Extjs 源码组成(4.0.7)

    (function(){})()形式的自执行,构建Ext对象(0~584) 1  设置全局对象EXt:global.Ext = {}, 2 实现了Ext对象面向对象编程的基础方法,如,apply,ex ...

  6. 《精通C#》自定义类型转化-扩展方法-匿名类型-指针类型(11.3-11.6)

    1.类型转化在C#中有很多,常用的是int类型转string等,这些都有微软给我们定义好的,我们需要的时候直接调用就是了,这是值类型中的转化,有时候我们还会需要类类型(包括结构struct)的转化,还 ...

  7. F:ungeon Master

    总时间限制: 1000ms 内存限制: 65536kB描述You are trapped in a 3D dungeon and need to find the quickest way out! ...

  8. ACCESS导入CSV文件出现乱码解决办法

    在ACCESS或Excel中导入CSV文件时常常出现乱码,这是因为简体中文版的windows操作系统及其应用软件默认都是ANSI/GBK编码,而导入的文件使用的编码与操作系统默认的编码不相符.出现这种 ...

  9. 动态获取R.drawable.xx资源

    String imageName = "index_fragmen"+getColor();final int resId = context.getResources().get ...

  10. 使用 AngularJS 和 Electron 构建桌面应用

    GitHub 的 Electron 框架(以前叫做 Atom Shell)允许你使用 HTML, CSS 和 JavaScript 编写跨平台的桌面应用.它是io.js 运行时的衍生,专注于桌面应用而 ...