最长回文串问题

manacher算法是用来求解最长回文串的问题。最长回文串的解法一般有暴力法、动态规划、中心扩展法和manacher算法。

  • 暴力法的时间复杂度为\(O(n^3)\),一般都会超时;
  • 动态规划的时间复杂度和空间复杂度均为\(O(n^2)\),通过矩阵压缩存储,空间复杂度常数可以降低为0.5,但时间复杂度较高,基本不能再优化;
  • 中心扩展法在性能上优于动态规划,空间复杂度为\(O(1)\),但时间复杂度仍然是\(O(n^2)\);
  • manacher性能最好,时间复杂度和空间复杂度均为\(O(n)\)

对中心扩展法的分析

//中心扩展法的代码
class Solution {
public:
string longestPalindrome(string s) {
if(s.size() == 0)return "";
int maxlen = 1, start = 0;
for(int i = 0; i < s.size(); ++i){
int len1 = expand(s, i, i);
int len2 = expand(s, i, i + 1);
int len = max(len1, len2);
if(len > maxlen){
start = i - (len - 1) / 2;
maxlen = len;
}
}
return s.substr(start, maxlen);
}
private : int expand(const string &s, int l, int r){
while(l >= 0 && r < s.size() && s[l] == s[r]){
l--;
r++;
}
return r - l - 1;
}
};

中心扩展法造成时间复杂度高的原因主要有两个方面:

  • 需要分奇数和偶数两种情况讨论;
  • 子串包含重复计算;

第一点从代码可以看出,第二点见插图:



对第 \(j\)个字符进行中心扩展时, 子串\(s[0, j - 1]\)都已经进行了中心扩展,以每个字符为中心的回文串信息都已经获得,在这些回文串中必然存在一个最长的回文串\(s[mx, my]\),其对称中心记作\(id\)。如果\(j < my\),则\(j\)一定有一个对称位置\(i\),假设以\(i\)为中心的回文串为左侧绿色的子串,则以\(j\)为中心的绿色子串一定也是回文串。但是中心扩展法忽略了这点,对这部分子串进行了重复比对。

manacher算法思想

manacher算法主要是对中心扩展法的两方面不足进行改进。

字符串预处理

为了不区分奇数和偶数两种情况,manacher对字符串进行了预处理,在长度为\(n\)的字符串的空隙中填入\(n+1\)相同的字符,使字符串的总长度变为\(2n + 1\)。

例如:

对于字符串abbac,处理之后为#a#b#b#a#c#(假设插入的字符为#

处理之后的字符串与原字符串的映射关系为:\(s[i] = temps[2 * i + 1]\)

\(i\)号位置之前有 \(i+1\)个gap

处理后的最大回文串长度与原来的长度的关系:\((tempLmax - 1) / 2 = lmax\)

算法实现

  • 数据结构

    • 回文半径数组\(radius[len]\)

      \(radius[i] = (tempLmax(i) - 1) / 2\),含义为字符\(temps[i]\)右侧的字符个数(不懂网上很多版本为什么带上\(temps[i]\))

    • 最大覆盖范围\((id, mx)\),\(id\)为对称中心

  • 算法实现

    • 每次在进行中心扩展时,先计算一个合适的扩展起点,而不是直接从当前位置直接扩展
    • 扩展的方法同中心扩展法相同
    • 每次扩展完毕,要更新最大覆盖范围\((id, mx)\)和最大长度

代码

string longestPalindrome(string s) {
if(s.size() == 0)return "";
string temps = "#";
for(int i = 0; i < s.size(); ++i){
temps += s[i];
temps += '#';
}
int len = temps.size();
int radius[len] = {0};
int id = 0, mx = 0;
int start = 0, maxlen = 0;
for(int i = 1; i < len; ++i){
if(i < mx){
radius[i] = min(radius[2 * id - i], mx - i);
}
for(int dl = radius[i] + 1; i - dl >= 0 && i + dl < len; ++dl){
if(temps[i - dl] == temps[i + dl])radius[i]++;
else break;
}
if(radius[i] + i > mx){
id = i;
mx = radius[i] + i;
}
if(radius[i] > maxlen){
start = (i - radius[i]) / 2;
maxlen = radius[i];
}
}
return s.substr(start, maxlen);
}

更详细的的介绍

【算法】Manacher算法的更多相关文章

  1. 经典算法 Manacher算法详解

    内容: 1.原始问题   =>O(N^2) 2.Manacher算法   =>O(N) 1.原始问题 Manacher算法是由题目“求字符串中长回文子串的长度”而来.比如 abcdcb 的 ...

  2. [转]O(n)回文子串算法 Manacher算法

    这里,我介绍一下O(n)回文串处理的一种方法.Manacher算法.原文地址:http://zhuhongcheng.wordpress.com/2009/08/02/a-simple-linear- ...

  3. [算法] Manacher算法线性复杂度内求解最长回文子串

    参考:http://www.felix021.com/blog/read.php?2040 以上参考的原文写得很好,解析的非常清楚.以下用我自己的理解,对关键部分算法进行简单的描述: 回文的判断需要完 ...

  4. 浅谈Manacher算法与扩展KMP之间的联系

    首先,在谈到Manacher算法之前,我们先来看一个小问题:给定一个字符串S,求该字符串的最长回文子串的长度.对于该问题的求解.网上解法颇多.时间复杂度也不尽同样,这里列述几种常见的解法. 解法一   ...

  5. ACM -- 算法小结(八)字符串算法之Manacher算法

    字符串算法 -- Manacher算法 首先介绍基础入门知识,以下这部分来着一贴吧,由于是很久之前看的,最近才整理一下,发现没有保存链接,请原创楼主见谅. //首先:大家都知道什么叫回文串吧,这个算法 ...

  6. Manacher算法总结

    部分图片转自:http://www.cnblogs.com/grandyang/p/4475985.html manacher算法(民间称马拉车算法233)是用来找字符串中的最长回文子串的,先来说一下 ...

  7. 最长回文子串(动规,中心扩散法,Manacher算法)

    题目 leetcode:5. Longest Palindromic Substring 解法 动态规划 时间复杂度\(O(n^2)\),空间复杂度\(O(n^2)\) 基本解法直接看代码 class ...

  8. [hdu3068 最长回文]Manacher算法,O(N)求最长回文子串

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意:求一个字符串的最长回文子串 思路: 枚举子串的两个端点,根据回文串的定义来判断其是否是回文 ...

  9. 使用manacher算法解决最长回文子串问题

    要解决的问题 求一个字符串最长回文子串是什么.且时间复杂度 O(N) 具体描述可参考: LeetCode_5_最长回文子串 LintCode_200_最长回文子串 暴力解法 以每个字符为中心向左右两边 ...

  10. Manacher算法讲解——字符串最长回文子串

    引 入 引入 引入 Manachar算法主要是处理字符串中关于回文串的问题的,这没什么好说的. M a n a c h e r 算 法 Manacher算法 Manacher算法 朴素 求一个字符串中 ...

随机推荐

  1. CF1291A Even But Not Even 题解

    Content 有 \(t\) 组数据,每组数据给定一个整数 \(n\),接着给出一个长度为 \(n\) 的数字串.请从中删除一些数,使得剩下的数字串不是偶数,但是其和为偶数,或者不存在这样的方案. ...

  2. IIS部署,发布网站

    一.IIS部署 1.打开控制面板,选择 '程序' 2.程序和功能下,选择打开或关闭Windows功能 3.等待加载,选择Internet信息服务,勾选如下选项 在弹出的"windows功能& ...

  3. Mybatis-Plus中使用max、sum聚合函数、只查询指定字段、查询语句多个OR处理

    聚合函数查询 可以使用以下方法 QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.select(" I ...

  4. 【LeetCode】LCP 06. 拿硬币

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 替换 日期 题目地址:https://leetcode ...

  5. A. Watchmen(Codeforces 650A)

    A. Watchmen time limit per test 3 seconds memory limit per test 256 megabytes input standard input o ...

  6. 1108 - Instant View of Big Bang

    1108 - Instant View of Big Bang   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limi ...

  7. Windows 11实现直播,VLC超简单实现捕获、串流、播放

    上一篇文章说了搭建Nginx的rtmp服务.实现直播功能 期间发现一个更便捷的工具 VLC media play,官方下载:https://www.videolan.org 1.傻瓜式安装,略过 2. ...

  8. 源码解析C#中PriorityQueue(优先级队列)的实现

    前言 前段时间看到有大佬对.net 6.0新出的PriorityQueue(优先级队列)数据结构做了解析,但是没有源码分析,所以本着探究源码的心态,看了看并分享出来.它不像普通队列先进先出(FIFO) ...

  9. 【Azure 应用服务】探索在Azure上设置禁止任何人访问App Service的默认域名(Default URL)

    问题描述 总所周知,Azure App Service服务会默认提供一个 ***.chinacloudsites.cn为后缀的域名,但是该域名由上海蓝云网络科技有限公司备案,仅用于向其客户提供 Azu ...

  10. windows下的Python的下载与安装

    Python的下载 Python下载要去官网下载,xdm,这里是网址 www.python.org 因为是外网所以打开下载会慢一些(不要着急的说) 这是python官网界面,跟着图片去下载(因为我这会 ...