百度了好长时间,看了很多篇博客才稍微看懂,所以自己写篇博客加深一下映像,并且写的尽量详细一些 希望大家能够只这篇博客就能看懂,能少走些弯路

马拉松算法

1.添加特殊字符

通常情况下,对于一个字符串,需要求解其最长子串时,我们通常需要考虑其字符长度的奇偶性问题,比如'aba'与'abba'的求解方式不太一样,但是马拉松算法在每个字符之间都添加了一个特殊字符(原字符串所没有的),比如'#'或'$'符号,比如'aba'==>'#a#b#a#','abba'==>'#a#b#b#a#',那么此时,无论之前字符长度是否为奇偶,现在都变成了奇数,此时我们只需要考虑这一种情况就可以了

为什么插入特殊字符后,字符串都变为奇数个字符了?

偶数情况: 假设我们有一个偶数个字符的字符串,我们令其字符数为a,此时我们为其插入特殊字符,特殊字符数为(两边各一个+中间插入a-1个)即有:插入后字符个数 = a+(a-1+2)=2a+1==> 因2a为偶数所以2a+1为奇数
奇数情况: 假设我们有一个奇数个字符的字符串,我们令其字符数为a+1,其a为偶数,此时我们插入特殊字符数为(两边各一个+中间插入a个)即有:插入后字符数=a+1+a+2=2a+3==>2a为偶数所以2a+3为奇数

如果我们令每一个字符都与自己构成回文数,并且记录其回文半径(以当前字符为中心,向两边扩散,如果字符对称则半径+1,直到出现不对称字符),比如单个字符'a'变为新字符串'#a#',新字符串的回文半径将为[1,2,1],此时我们可以写一下代码

 1     public static void test(String str) {
 2
 3         /* 向字符串插入特殊字符 */
 4         List<Character> strs=new ArrayList<>();
 5
 6         strs.add('#');
 7         for (int i = 0; i < str.length(); i++) {
 8             strs.add(str.charAt(i));
 9             strs.add('#');
10         }
11
12         /* 存储每位字符的最大回文半径 */
13         int[] len=new int[strs.size()];
14         /* 最大回文字串的中心位置 */
15         int id=0;
16
17         /* 遍历新字符串 */
18         for (int i = 0; i < strs.size(); i++) {
19
20             while(i-len[i]>=0&&i+len[i]<strs.size()&&strs.get(i-len[i])==strs.get(i+len[i])) {
21                 len[i]++;
22             }
23
24             /* 如果新查找串更长 则替换最长回文字串的中心位置 */
25             if(len[i]>len[id]) {
26                 id=i;
27             }
28         }
29
30         for (int i = id-(len[id]-1); i <= id+(len[id]-1); i++) {
31             System.out.print(strs.get(i));
32         }
33     }

测试一下

    public static void main(String[] args) {test("123242329");}

  结果: #2#3#2#4#2#3#2#

此时我们已经能获取到最长字串了,当然这还远远不能算是马拉松算法,见图片

代码

 1     public static void manacher(String str) {
 2
 3         /* 向字符串插入特殊字符 */
 4         List<Character> strs=new ArrayList<>();
 5
 6         strs.add('#');
 7         for (int i = 0; i < str.length(); i++) {
 8             strs.add(str.charAt(i));
 9             strs.add('#');
10         }
11
12         /* 存储每位字符的最大回文半径 */
13         int[] len=new int[strs.size()];
14         /* 最大回文字串的中心位置 */
15         int id=0;
16         /* 最大回文字串的右边界 */
17         int mxindex=0;
18
19         /* 遍历新字符串 */
20         for (int i = 0; i < strs.size(); i++) {
21             /* 如果 i在最大回文串中 则可以进行一些判断 */
22             if(i<mxindex) {
23                 /* 判断i点关于最大字串中心对称点j的回文半径长度 */
24                 int j=2*id-i;
25
26                 /**
27                  * 当字符串                        "# 1 # 2 # 3 # 2 # 4 # 2 # [3] # 2 # 9 #"
28                  *     运行到3位置时,其左边字符必定全部计算过回文数了
29                  *     此时最大的回文串为                "# 1 # 2 # 3 # 2 # $4$ # 2 # [3] # 2 #"
30                  *     右3包含与其中 并且位于中心字符$4$的右边
31                  *     此时根据对称原则找到3的对称点\3\
32                  *                                 "# 1 # 2 # \3\ # 2 # $4$ # 2 # [3] # 2 #"
33                  *     此时的对称点\3\必然已经计算过了,而其回文半径有一下几种情况
34                  *  1.  对称点\3\的回文半径在在最长回文之内 根据对称原则 此时计算点回文半径必然也为此值
35                  *  2.  对称点\3\的回文半径超过了最长回文字符,此时计算点回文半径应为对称点\3\到左边界的长度
36                  *  3.  对称点\3\的回文半径刚好在最长回文边界处 此时计算点的回文半径为[对称点回文半径+继续暴力求解]
37                  *
38                  *///1.2.两种情况都不会为最长回文子串 所以只需要设置其回文半径就可以
39                 if(len[j]<mxindex-i) {
40                     len[i]=len[j];
41                     continue ;
42                 }else if(len[j]>mxindex-i) {
43                     len[i]=mxindex-i;
44                     continue ;
45                 }else if(len[j]==mxindex-i) {
46                     len[i]=len[j];
47                 }
48             }
49
50
51             while(i-len[i]>=0&&i+len[i]<strs.size()&&strs.get(i-len[i])==strs.get(i+len[i])) {
52                 len[i]++;
53             }
54
55             /* 如果新查找串更长 则替换最长回文字串的中心位置 */
56             if(len[i]>len[id]) {
57                 mxindex=i+len[i]-1;
58                 id=i;
59             }
60         }
61
62         for (int i = id-(len[id]-1); i <= id+(len[id]-1); i++) {
63             System.out.print(strs.get(i));
64         }
65     }
66     


如果有地方写的错误,或者有什么疑问与建议,欢迎大家提出来 愿与大家一同进步

转载于:https://www.cnblogs.com/wangbingc/p/10217139.html

最长回文子串 -- 马拉松算法相关推荐

  1. HihoCode1032 最长回文子串 manacher算法

    求最长回文子串的算法比较经典的是manacher算法 转载自这里 首先,说明一下用到的数组和其他参数的含义: (1)p[i] : 以字符串中下标为的字符为中心的回文子串半径长度: 例如:abaa字符串 ...

  2. 【字符串】最长回文子串 ( 动态规划算法 ) ★

    文章目录 一.回文串.子串.子序列 二.最长回文子串 1.动态规划算法 2.动态规划算法代码示例 一.回文串.子串.子序列 " 回文串 ( Palindrome ) " 是 正反都 ...

  3. 【字符串】最长回文子串 ( 蛮力算法 )

    文章目录 一.回文串.子串.子序列 二.最长回文子串 1.蛮力算法 2.时间复杂度最优方案 一.回文串.子串.子序列 " 回文串 ( Palindrome ) " 是 正反都一样的 ...

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

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

  5. 求解最长回文子串----Manacher 算法

    最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字符串正着读和反着读是一样的,那么我们称之为回文串.例如:abba.aaaa.abvcba.123321等 暴力法:遍历字符串的所有 ...

  6. 最长回文子串——Manacher 算法​​​​​​​

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

  7. 最长回文子串 : Marcher算法

    相应leetcode题目 leetcode 第5题. 最长回文子串 1.回文串 即从两边开始到中间,对应的字符都相同 public boolean isPalindrome(String str){i ...

  8. 最长回文子串manacher算法模板

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

  9. 最长回文子串(马拉车算法)

    给出一个字符串:cabadabae 我们不难看出其回文子串:aba,abadaba 这边简单介绍两种做法: 1.暴力:找出所有字串,然后依次判断是否为回文串,最后找出最长的回文子串 2.中心扩展:遍历 ...

最新文章

  1. linux下SublimeText的中文输入法问题之解决方案
  2. SNMP功能开发简介 二 net-snmp源码分析报文处理流程图
  3. 中国太阳能热水器市场营销模式探析与品牌格局调研报告2022版
  4. SpringMVC的Controller方法返回值
  5. android 书架菜单,Android入门3--做一个书架
  6. oracle删除当前用户下所有表
  7. python with关键字_python中用with关键字来实现上下文管理器.
  8. oracle gather trace,Oracle 12C R2-新特性-新增两个视图:方便查看trace文件和内容
  9. EVEREST Ultimate Edition 4.50 Build 1330 Final
  10. java和python和php_Java、Python和PHP三者的区别
  11. 日本研发投篮机器人Cue,投球命中率接近100%
  12. Ubuntu Linux系统备份与还原命令技巧
  13. 深入了解JVM的底层原理
  14. IEEE论文latex模板
  15. IBM将花2.5亿收购第二家以色列移动软件开发商
  16. 基于C# WinForms窗体——飞机大战
  17. 毁灭战士 DOOM 3DO 源代码公开
  18. Canvas画环形圆
  19. 多线程与单线程的区别
  20. 618投影仪怎么选?看看极米NEW Z6X、极米Z6X Pro与极米H3S

热门文章

  1. 那些停课的日子 by yjjr
  2. 微信现金红包签名失败问题
  3. Unity 动画混合树实例(Blend Tree)
  4. css 填满剩余高度
  5. 【BZOJ1997】【HNOI2010】Planar(2-SAT,平面图,并查集)
  6. layui form表单提php验证,Layui-表单验证 - CLTPHP-内容管理系统_php cms_开源CMS_CLTPHP-内容管理系统...
  7. 前端必备的截屏取色小工具推荐——Faststone Capture
  8. 拯救工程师,远程开发C++的四大秘笈|视频教程
  9. 卓越工程师宣传口号,关键词:实干善为 智创未来;六新工匠 两商领军;六新工匠 智创未来;六新工匠实干巧干善干 技术智慧创优创效创新,再写一篇定位理解,100字以内...
  10. 洛谷3376 网络最大流