马拉车算法详解, C++代码实现
算法介绍
马拉车算法是用来在一个字符串中寻找最长回文串(正着读和反着读都相同的字符串)的一种算法。
该算法运用了动态规划的思想,将寻找最长回文串算法的时间复杂度降低到了线性。
算法原理
对于一个字符串要判断它是否为回文串要分为字符串长度为奇数或者偶数两种情况,为了简化做法,我们进行如下的操作:
- 在字符串的两端和每两个字符中间添加一个 ‘#’ (或者任意一个一定不会在字符串中出现的字符, 通常就是 ‘#’ 啦)
- 再在字符串的开始和结尾放置字符串开始和结束的标识符。
上述操作后拓展出来的字符串的长度一定是奇数。
例如:
abcd 拓展后变为 ^#a#b#c#d#$
abc 拓展后变为 ^#a#b#c#$
要将算法的复杂度降低到线性,我们就要用到动态规划的思想。
这里我们定义了一个dp数组,其中dp[i]定义为以下标为i的字符作为回文串中心的回文半径 (从中心元素到左边界或右边界的字符长度) 的大小。
这里举个例子
s[] = "abac"str[] ^ # a # b # a # c # $
dp[] 1 2 1 4 1 2 1 2 1
我们得出dp数组后问题就可以解决了,所以接下来就是要着力求解dp数组了。
动态规划的核心便是通过之前的计算来简化之后要进行的计算,我们这里再引入两个量来实现这个过程:
int right; // 在计算过程中用于记录寻找到所有子回文串中右边界的下标
int pos; // 用于记录右边界就是right的子回文串的下标
接下来就是算法的关键了我们要逐次求出dp[i]的值:
我们在计算dp[i]时首先考虑这个值之前是否计算过,这里要充分利用回文串的特点。
----------------------------------------------------^ ^ ^|<--------------------|-------------------->|left pos right
如果 i 在 pos 和 right 之间,则可以寻找 i 关于 pos 的对称点,这时可以先假设dp[i] = dp[2*pos-i]
,这个假设并不在任何情况下都成立:
如果中心为 2*pos-i 的回文串覆盖的区域左边界超过了left,则这个回文串中存在一些可能不在中心为 i 的回文串中的元素,这种情况下dp[i] = right-i
将上述讨论的情况结合起来即可得到:
dp[i] = min(dp[2*pos-i], right-i)
如果 i > right
那我们就用暴力的方法求解dp[i]即可
算法实现
int Manacher(char* s) {int len = strlen(s+1);char str[2*len+10];int dp[2*len+10];int cur = 0;str[0] = '^';for(int i = 0; i < len; ++i) {str[++cur] = '#';str[++cur] = s[i];}str[++cur] = '#', str[++cur] = '$';int right = 0, pos = 0;for(int i = 1; i <= cur; ++i) {if(i < right)dp[i] = min(dp[2*pos-i], right-i);elsedp[right=i] = 1;while(str[i-dp[i]] == str[i+dp[i]])++dp[i];if(i+dp[i] > right)right = i+dp[i], pos = i;}return *max_element(dp+1, dp+cur+1)-1;
}
特别感谢
感谢我女朋友对我的大力支持
马拉车算法详解, C++代码实现相关推荐
- Manacher Algorithm马拉车算法详解
Manacher Algorithm马拉车算法详解 链接:https://www.zhihu.com/question/37289584/answer/465656849 中心扩展算法 我们先来看一个 ...
- 粒子群(pso)算法详解matlab代码,粒子群(pso)算法详解matlab代码
粒子群(pso)算法详解matlab代码 (1)---- 一.粒子群算法的历史 粒子群算法源于复杂适应系统(Complex Adaptive System,CAS).CAS理论于1994年正式提出,C ...
- 数学建模——主成分分析算法详解Python代码
数学建模--主成分分析算法详解Python代码 import matplotlib.pyplot as plt #加载matplotlib用于数据的可视化 from sklearn.decomposi ...
- Go-AES算法详解与代码
目录 AES 发展史 概述 轮函数F 字节代换 行移位 列混淆 轮密钥加 密钥编排 AES和DES的不同之处 分组模式CTR AES的Go实现 aes包 cipher包 加密/解密 参考 本篇介绍分组 ...
- 【分享实录】BANCOR算法详解及代码实现
1 活动基本信息 1)主题:[区块链技术工坊22期]BANCOR算法详解及代码实现 2)议题: BANCOR算法的特点和优劣势 BANCOR算法和举例 如何加入BANCOR.NETWORK交易所 如何 ...
- 技术工坊|BANCOR算法详解及代码实现(上海)
2019独角兽企业重金招聘Python工程师标准>>> EOS项目在RAM分配中采用了Bancor算法,并将RAM的价格爆炒到了很高的价位,凭借EOS项目在区块链领域的强大运营宣传能 ...
- 【区块链技术工坊22期实录】王登辉:BANCOR算法详解及代码实现
1,活动基本信息 1)题目: [区块链技术工坊22期]BANCOR算法详解及代码实现 2)议题: 1)BANCOR算法的特点和优劣势 2)BANCOR算法和举例 3)如何加入BANCOR.NETWOR ...
- 算法 经典的八大排序算法详解和代码实现
算法 经典的八大排序算法详解和代码实现 排序算法的介绍 排序的分类 算法的时间复杂度 时间频度 示例 图表理解时间复杂度的特点 时间复杂度 常见的时间复杂度 空间复杂度 排序算法的时间复杂度 冒泡排序 ...
- [联邦学习] FedAvg聚合算法详解及代码实现
该文章首发于若绾 [联邦学习] FedAvg聚合算法详解及代码实现,转载请标注出处. 论文原文:Communication-Efficient Learning of Deep Networks fr ...
- KMP算法详解及代码
KMP算法详解及代码 KMP算法详解及代码 定义及应用 理论 基本概念 next 数组 总结 注意 代码 KMP算法详解及代码 最近正好在看字符串相关的算法内容,就顺便把KMP算法回顾了一下.相应的代 ...
最新文章
- 转 Debugging AutoCAD 2017 using Visual Studio 2015
- FlinkX 如何读取和写入 Clickhouse?
- 面向对象设计启发规则
- 链地址处理哈希冲突方法
- 文具用品分类html,中国商品分类.doc
- shell脚本修改文本中匹配行之前的行的方法
- 统信 UOS 适配支持百度飞桨 AI 深度学习平台;阿里回应“马云遭印度法院传唤”;fastjson 1.2.73 发布 | 极客头条
- C#中的方法(函数),委托和事件
- 反编译,修改jar文件
- 【Proteus仿真】矩阵键盘中断扫描
- 什么是平面设计?详细讲解平面设计
- null id in entry (don‘t flush the Session after an exception occurs)解决思路
- 解决大篇幅pdf中英文复制时,粘贴到word中自动换行的问题
- SAP JCo 功能
- Latex入门篇之论文排版
- 数据库学习 (一):数据库系统概述
- 函数TEXT - 补0实现数字固定位数输出
- python遇到执行超时如何跳过避免任务卡死
- VsCode 使用less
- 【Linux操作系统】基础概念和常用指令(一)