java最长回文子串(Manacher算法的详细讲解)

2026-05-16 05:00:01 :0

java最长回文子串(Manacher算法的详细讲解)

各位老铁们,大家好,今天由我来为大家分享java最长回文子串,以及Manacher算法的详细讲解的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!

本文目录

Manacher算法的详细讲解

Manacher算法,又叫“马拉车”算法,可以在时间复杂度为O(n)的情况下求解一个字符串的最长回文子串长度的问题。

比较简单的思路是将字符串的每一个字符作为回文子串的中心对称点,每次保存前面求得的回文子串的最大值,最后得到的就是最长的回文子串的长度,这种方式的时间复杂度是O(n^2)。在求解过程中,基数的回文子串与偶数的回文子串是不一样的。比如最长回文子串为aba,对称中心就是b,如果最长回文子串为abba,则对称中心应该为两个b之间,为了解决这个问题,可以在每个字符两边加上一个符号,具体什么符号(是字符串里面的符号也行)对结果没有影响,比如加上“#”,则上述的两个序列变成了#a#b#a#和#a#b#b#a#,求出的长度分别为6和9,再除以2就可以得到最后的结果3和4。这种方式的时间复杂度太高,下面介绍时间复杂度为O(n)的Manacher算法。

在进行Manacher算法时,字符串都会进行上面的进入一个字符处理,比如输入的字符为acbbcbds,用“#”字符处理之后的新字符串就是#a#c#b#b#c#b#d#s#。

回文半径数组radius是用来记录以每个位置的字符为回文中心求出的回文半径长度,如下图所示,对于p1所指的位置radius。

一个位置最右回文右边界指的是这个位置及之前的位置的回文子串,所到达的最右边的地方。比如对于字符串#a#c#b#b#c#b#d#s#,求它的每个位置的过程如下:

最开始的时候R=-1,到p=0的位置,回文就是其本身,最右回文右边界R=0;p=1时,有回文串#a#,R=2;p=2时,R=2;P=3时,R=6;p=4时,最右回文右边界还是p=3时的右边界,R=6,依次类推。

就是上面提到的最右回文右边界的中心点C,如下图,p=4时,R=6,C=3

首先大的方面分为两种情况:

第一种情况:下一个要移动的位置在最右回文右边界R的右边。

比如在最开始时,R=-1,p的下一个移动的位置为p=0,p=0在R=-1的右边;p=0时,此时的R=0,p的下一个移动位置为p=1,也在R=0的右边。

在这种情况下,采用普遍的解法,将移动的位置为对称中心,向两边扩,同时更新回文半径数组,最右回文右边界R和最右回文右边界的对称中心C。

第二种情况:下一个要移动的位置就是最右回文右边界R或是在R的左边

在这种情况下又分为三种:

1、下一个要移动的位置p1 不在 最右回文右边界R右边,且cL《pL。

p2是p1以C为对称中心的对称点;

pL是以p2为对称中心的回文子串的左边界;

cL是以C为对称中心的回文子串的左边界。

这种情况下p1的回文半径就是p2的回文半径radius。

2、下一个要移动的位置票p1 不在 最右回文右边界R的右边,且cL》pL。

p2是p1以C为对称中心的对称点;

pL是以p2为对称中心的回文子串的左边界;

cL是以C为对称中心的回文子串的左边界。

这种情况下p1的回文半径就是p1到R的距离R-p1+1。

3、下一个要移动的位置票p1 不在 最右回文右边界R的右边,且cL=pL;

p2是p1以C为对称中心的对称点;

pL是以p2为对称中心的回文子串的左边界;

cL是以C为对称中心的回文子串的左边界。

这种情况下p1的回文半径就还要继续往外扩,但是只需要从R之后往外扩就可以了,扩了之后更新R和C。

从上面的分析中,可以看出,第二种情况的1,2的求某个位置的回文半径的时间复杂度是O(1),对于第一种情况和第二种情况的3,R是不断的向外扩的,不会往回退,而且寻找回文半径时,R之内的位置是不是进行判断的,所以对整个字符串而且,R的移动是从字符串的起点移动到终点,时间复杂度是O(n),所以整个manacher的时间复杂度是O(n)。

java 编写一个方法,找出一个字符串中最长的回文子串

Java code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import java.util.ArrayList;
import java.util.List;
public class Palindrome {
/* 找出一个字符串中最长的回文子串
* 从字符串中第i个字符开始的所有非空回文子串的个数, 记作为Ci. 此方法的复杂度为
* O(C1 + C2 + ... + Cn)
* 当字符串中任意两个非空回文子串的起始位置不同时, C1 = C2 = ... = Cn = 1, 复杂度为O(N);
* 当字符串所有字符均为同一字符时, Ci = n - i, 此时复杂度为O(N*N);
* 在多数情况下, 此方法的复杂度远低于O(N*N).
*/
public List《String》 getLongestPalindrome(String theString) {
int strLen = theString.length();
List《String》 results = new ArrayList《String》(strLen);
if (strLen == 0) {
return results;
}
// 从第i个位置开始的所有回文子串的结束位置.
int;
// endIndice中有效数据的长度.
int numberOfPalindromes = 1;
// 最长回文子串的长度. 对于非空串至少可以找到长度为1的回文子串.
int maxLen = 1;
results.add(theString.substring(strLen - 1));
// 计算从第i个位置开始的所有回文子串. 这样的子串分为三种:
// 1. 在从第i+1个位置开始的回文子串的基础上, 在两端加上相同的字符;
// 2. 长度为1的回文子串;
// 3. 空串.
for (int i = strLen - 2; i 》= 0; i--) {
int j = 0, k = 0;
while (j 《 numberOfPalindromes) {
if (theString.charAt(i) == theString.charAt(endIndice)) {
endIndice + 1;
int newLength = endIndice - i;
if (newLength 》= maxLen) {
if (newLength 》 maxLen) {
maxLen = newLength;
results.clear();
}
results.add(theString.substring(i, endIndice));
}
if (endIndice 《 strLen) {
k++;
}
}
j++;
}
// 加入长度为1的子串
endIndice = i + 1;
if (maxLen == 1) {
results.add(theString.substring(i, i + 1));
}
// 加入空串
endIndice = i;
numberOfPalindromes = k;
}
return results;
}
public static void main(String args) {
Palindrome p = new Palindrome();
printList(p.getLongestPalindrome("gabcecbaefd"));
printList(p.getLongestPalindrome("bbcbaefccfg"));
printList(p.getLongestPalindrome("aaaaaaaaaaa"));
printList(p.getLongestPalindrome("abcdefghijk"));
printList(p.getLongestPalindrome("abcdeeddejk"));
printList(p.getLongestPalindrome(""));
}
public static void printList(List《? extends Object》 list) {
System.out.println("**************************");
System.out.println(list.size() + " result(s):");
for (Object o : list) {
System.out.println(o);
}
}
}

巧用贪心算法,计算出字符串回文

给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。

在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。

注意:
假设字符串的长度不会超过 1010。

示例 1:

输入:
"abccccdd"

输出:
7

解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。

给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。

请注意!!!

题目的意思是:利用这个字符串中的所有字母来构造最长回文串,是构造!是可以改变字母出现的位置顺序的!字母位置可以任意移动。而不是在顺序不变的情况下找出最长的回文串。

作者一开始粗心大意没理解题意,直接上手做题吃大亏(捂脸。

现在来解释下,什么是回文?

回文串是一个正着读和反着读都一样的字符串。

来看两个不同的回文例子:

AB|BA。仅看字母,我们发现,AB和BA根据中心竖线|对称,这个回文串长度为4,每个字母出现的次数都是偶数。
ABCBA。我们发现,AB和BA根据字母C对称,这个回文串长度为5,除了对称中心的字母C仅出现过一次外,中心两边的字母出现次数都是偶数。
所以我们可以总结出,如果想要构造出一个回文串,除了回文串中心的字母只能出现一次外(如果有中心字母的话),中心两边的字母还需对称出现,即出现偶数次。

解决了构造回文串这一关键点,题目中还有一个特别之处:仅出现大写字母和小写字母。

如果对英文字母的Unicode编码熟悉的话,可以知道,字母A的Unicode编码是65(十进制),字母Z的Unicode编码是90(十进制),字母a的Unicode编码是97(十进制),字母z的Unicode编码是122(十进制)。

可以发现它们是Unicode编码是连续(中间的91到96并不重要),即有序的,所以可以使用数组来存放它们,每个数组项的值就是每个字母出现的次数。

这种情况下,使用数组来存储,会比使用哈希表(Map)来存储来得更高性能,哪怕Unicode编码的91到97我们无需使用。

且,在JavaScript世界中,可以使用String.prototype.charCodeAt()这一API来获取Unicode编码单元。

所以,我们可以这样来统计每个字母出现的次数:

关于java最长回文子串到此分享完毕,希望能帮助到您。

java最长回文子串(Manacher算法的详细讲解)

本文编辑:admin

更多文章:


万维书刊网怎么下载书刊手机?万维书刊网的点评能撤回吗

万维书刊网怎么下载书刊手机?万维书刊网的点评能撤回吗

各位老铁们好,相信很多人对万维期刊网都不是特别的了解,因此呢,今天就来为大家分享下关于万维期刊网以及万维书刊网怎么下载书刊手机的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!本文目录万维书刊网怎么下载书刊手机万维书刊网的

2026年7月14日 22:15

apache历史版本安装(xampp设置域名访问后,以前设置的非域名访问方式就无效了)

apache历史版本安装(xampp设置域名访问后,以前设置的非域名访问方式就无效了)

大家好,如果您还对apache历史版本安装不太了解,没有关系,今天就由本站为大家分享apache历史版本安装的知识,包括xampp设置域名访问后,以前设置的非域名访问方式就无效了的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始

2026年2月11日 03:00

lip是什么意思?eclipse如何配置jdk

lip是什么意思?eclipse如何配置jdk

各位老铁们好,相信很多人对lip都不是特别的了解,因此呢,今天就来为大家分享下关于lip以及lip是什么意思的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!本文目录lip是什么意思eclipse如何配置jdkeclips

2025年9月16日 20:30

misunderstand用法(understand的反义词)

misunderstand用法(understand的反义词)

“misunderstand用法”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看misunderstand用法(understand的反义词)!本文目录understand的反义词misunderstanding后跟什么介词

2025年12月9日 00:45

oracle 12g(oracle 12g创建用户必须加c##吗)

oracle 12g(oracle 12g创建用户必须加c##吗)

大家好,关于oracle 12g很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于oracle 12g创建用户必须加c##吗的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位

2025年6月18日 12:00

幻灯片制作时应当做到(PPT制作应注意什么问题)

幻灯片制作时应当做到(PPT制作应注意什么问题)

本篇文章给大家谈谈幻灯片制作时应当做到,以及PPT制作应注意什么问题对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。本文目录PPT制作应注意什么问题

2025年7月10日 14:45

伦勃朗光影绘画(西方古典绘画的造型手法是什么)

伦勃朗光影绘画(西方古典绘画的造型手法是什么)

大家好,今天小编来为大家解答以下的问题,关于伦勃朗光影绘画,西方古典绘画的造型手法是什么这个很多人还不知道,现在让我们一起来看看吧!本文目录西方古典绘画的造型手法是什么对伦勃朗“光与影”技巧有什么高的评价伦勃朗光与三角光的区别是什么吹爆的水

2025年5月26日 21:15

表格科学计数法转换成数字(大于10的科学计数法怎么转换成数字)

表格科学计数法转换成数字(大于10的科学计数法怎么转换成数字)

本篇文章给大家谈谈表格科学计数法转换成数字,以及大于10的科学计数法怎么转换成数字对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录大于10的科学计数法怎么转换成数字Excel中,如何把科学记数法转换成数字EXCEL中怎样把科学

2026年3月4日 22:15

load error怎么解决(su(sketchup)进去的时候出现 load errors)

load error怎么解决(su(sketchup)进去的时候出现 load errors)

大家好,load error怎么解决相信很多的网友都不是很明白,包括su(sketchup)进去的时候出现 load errors也是一样,不过没有关系,接下来就来为大家分享关于load error怎么解决和su(sketchup)进去的时

2025年8月31日 16:00

fopen连续打开同一文件(怎样以循环的方式用fopen打开一系列文件)

fopen连续打开同一文件(怎样以循环的方式用fopen打开一系列文件)

本篇文章给大家谈谈fopen连续打开同一文件,以及怎样以循环的方式用fopen打开一系列文件对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。本文目录

2025年11月27日 05:30

react native怎么样(react native开发app好用么)

react native怎么样(react native开发app好用么)

大家好,关于react native怎么样很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于react native开发app好用么的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希

2025年6月4日 02:15

matlab编写递归函数(急急急!!写一个MATLAB递归函数combinat.m,其功能是可对输入字符串进行组合求各位大侠帮忙)

matlab编写递归函数(急急急!!写一个MATLAB递归函数combinat.m,其功能是可对输入字符串进行组合求各位大侠帮忙)

大家好,matlab编写递归函数相信很多的网友都不是很明白,包括急急急!!写一个MATLAB递归函数combinat.m,其功能是可对输入字符串进行组合求各位大侠帮忙也是一样,不过没有关系,接下来就来为大家分享关于matlab编写递归函数和

2025年7月24日 07:45

晋江json解析异常(python解析较大的json文件报异常,怎么处理)

晋江json解析异常(python解析较大的json文件报异常,怎么处理)

各位老铁们,大家好,今天由我来为大家分享晋江json解析异常,以及python解析较大的json文件报异常,怎么处理的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们

2025年12月18日 13:30

新冠重组cho疫苗(新冠疫苗打几针)

新冠重组cho疫苗(新冠疫苗打几针)

本篇文章给大家谈谈新冠重组cho疫苗,以及新冠疫苗打几针对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录新冠疫苗打几针新冠疫苗cho细胞是什么意思 新冠疫苗cho细胞的解释cho细胞新冠疫苗有什么用重组新型冠状病毒疫苗(CHO

2025年11月15日 00:30

不会编程能玩树莓派吗(树莓派可以用go语言写吗)

不会编程能玩树莓派吗(树莓派可以用go语言写吗)

各位老铁们好,相信很多人对不会编程能玩树莓派吗都不是特别的了解,因此呢,今天就来为大家分享下关于不会编程能玩树莓派吗以及树莓派可以用go语言写吗的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!本文目录树莓派可以用go语言

2025年12月28日 09:30

tcl电视轮播台在哪(tcl电视机怎么调出电视频道(长虹电视切换电视频道))

tcl电视轮播台在哪(tcl电视机怎么调出电视频道(长虹电视切换电视频道))

今天给各位分享tcl电视机怎么调出电视频道(长虹电视切换电视频道)的知识,其中也会对tcl电视机怎么调出电视频道(长虹电视切换电视频道)进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录tcl电视机怎么调出电视频

2025年7月16日 23:45

frameset标签的属性(在html标签中的frameset是什么标签 又有哪些属性和值)

frameset标签的属性(在html标签中的frameset是什么标签 又有哪些属性和值)

大家好,今天小编来为大家解答以下的问题,关于frameset标签的属性,在html标签中的frameset是什么标签 又有哪些属性和值这个很多人还不知道,现在让我们一起来看看吧!本文目录在html标签中的frameset是什么标签 又有哪些

2025年12月6日 02:15

matlab序列号数量限制(matlab中行向量或列向量最多能有多少个元素,元素太多就会出现out of memory的错误)

matlab序列号数量限制(matlab中行向量或列向量最多能有多少个元素,元素太多就会出现out of memory的错误)

大家好,matlab序列号数量限制相信很多的网友都不是很明白,包括matlab中行向量或列向量最多能有多少个元素,元素太多就会出现out of memory的错误也是一样,不过没有关系,接下来就来为大家分享关于matlab序列号数量限制和m

2026年2月28日 19:00

java反射教程(java中斜杠“/“和反斜杠“\分别代表什么意思“)

java反射教程(java中斜杠“/“和反斜杠“\分别代表什么意思“)

今天给各位分享java中斜杠“/“和反斜杠“\分别代表什么意思“的知识,其中也会对java中斜杠“/“和反斜杠“\分别代表什么意思“进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录java中斜杠“/“和反斜杠“

2025年6月21日 02:00

为什么getmonth要加一(js中获得月份getmonth()+1,为什么要加1)

为什么getmonth要加一(js中获得月份getmonth()+1,为什么要加1)

其实为什么getmonth要加一的问题并不复杂,但是又很多的朋友都不太了解js中获得月份getmonth()+1,为什么要加1,因此呢,今天小编就来为大家分享为什么getmonth要加一的一些知识,希望可以帮助到大家,下面我们一起来看看这个

2026年8月20日 11:45

近期文章

本站热文

electronics软件(labcenter electronics是什么软件)
2025-05-22 23:45:02 浏览:134
博客是微博吗(博客是微博吗)
2025-05-22 22:45:01 浏览:111
diversity and distribution(悬赏英语短文)
2025-05-23 16:15:02 浏览:107
ios软件开发前景(iOS就业前景怎么样)
2025-05-22 23:00:01 浏览:102
next month(有The next month这个单词吗,和 next month有什么区别)
2025-05-23 02:30:01 浏览:102
patron(patron是什么意思)
2025-05-23 10:30:02 浏览:95
标签列表

热门搜索