KMP算法复杂度证明
引言
KMP算法应该是看了一次又一次,比赛的时候字符串不是我负责,所以学到的东西又还给网上的博客了……
退役后再翻开看,看到模板,心想这不是\(O(n^2)\)的复杂度吗?
有两个循环也不能看做是\(O(n^2)\)的,这要用到摊还分析.
模板
这里用到的模板是算竞上的
calc_next()
Next[1] = 0;
for (int i = 2, j = 0; i <= n; ++i) {
while (j > 0 && a[i] != a[j + 1]) j = Next[j];
if (a[i] == a[j + 1]) ++j;
Next[i] = j;
}
kmp()
for (int i = 1, j = 0; i <= m; ++i) {
while (j > 0 && (j == n || b[i] != a[j + 1]))j = Next[j];
if (b[i] == a[j + 1])++j;
f[i] = j;
}
可以发现上下两个函数挺像的,Next[i]含义就是模式串以\(i\)结尾的子串([1..i]的后缀)与模式串的前缀能匹配的最长长度
证明
观察发现有两个操作:
- 匹配成功:
j++,这个代价是1 - 匹配失败:
j=Next[j]还要经过while循环,这个代价未知
根据记账法,假设每个平摊代价是2,对于每个匹配成功的操作,其中1元用来j++,另1元就存起来,给后面匹配失败时用:

而当失配的时候,就会用到银行存款,最坏的情况当然就是用光了所有存款,但可以发现每个匹配的操作分配两个时间代价是完全足够的
换句话说,你使用存款肯定得要求银行有存款,而每次j++操作都会存1元,在当前j前面必然每个位置都是有大于等于1的存款
所以复杂度就是j++次数的两倍,也就是匹配串的长度 \(2n\)
根据平摊分析要求\(\check c_i \ge c_i\),平摊代价设置为\(2\)是完全满足的
综上所述:KMP算法两个函数的总体运算次数为\(2n+2m\),复杂度是\(O(n+m)\)
总结
也不知道这样分析对不对,如果只是感性理解的话足够了.
也有势能法的做法,但是这样的话就要定义势能函数,我觉得记账法还是好理解一点.
KMP算法复杂度证明的更多相关文章
- KMP算法的正确性证明及一个小优化
直接把作业帖上来是不是有点不太公道呀... 无所谓啦反正各位看着开心就行 KMP算法 对于模式串$P$,建立其前缀函数$ N$ ,其中$N [q] $ 表示在$P$中,以$q$位置为结束的可以匹配到前 ...
- 算法导论17:摊还分析学习笔记(KMP复杂度证明)
在摊还分析中,通过求数据结构的一系列的操作的平均时间,来评价操作的代价.这样,即使这些操作中的某个单一操作的代价很高,也可以证明平均代价很低.摊还分析不涉及概率,它可以保证最坏情况下每个操作的平均性能 ...
- 浅析KMP算法
浅析KMP算法 KMP算法是一种线性字符串的匹配算法,将主串S与模式串T匹配. 首先朴素算法大家都会,就是直接从S的每一个位置开始,枚举比较,时间效率为O(nm),现在要想到一种化简的方式,使得时间复 ...
- 字符串匹配算法——KMP算法学习
KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...
- 关于KMP算法理解(快速字符串匹配)
参考:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 2016-08- ...
- 【BZOJ3670】动物园(KMP算法)
[BZOJ3670]动物园(KMP算法) 题面 BZOJ 题解 神TM阅读理解题 看完题目之后 想暴力: 搞个倍增数组来跳\(next\) 每次暴跳\(next\) 复杂度\(O(Tnlogn)\) ...
- 算法进阶面试题01——KMP算法详解、输出含两次原子串的最短串、判断T1是否包含T2子树、Manacher算法详解、使字符串成为最短回文串
1.KMP算法详解与应用 子序列:可以连续可以不连续. 子数组/串:要连续 暴力方法:逐个位置比对. KMP:让前面的,指导后面. 概念建设: d的最长前缀与最长后缀的匹配长度为3.(前缀不能到最后一 ...
- 【BZOJ3670】【NOI2014】动物园(KMP算法)
[BZOJ3670]动物园(KMP算法) 题面 BZOJ 题解 神TM阅读理解题 看完题目之后 想暴力: 搞个倍增数组来跳\(next\) 每次暴跳\(next\) 复杂度\(O(Tnlogn)\) ...
- 简单有效的kmp算法
以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...
随机推荐
- spring 动态bean注册
1. import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory. ...
- 51nod 1430:奇偶游戏 博弈
1430 奇偶游戏 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 收藏 关注 有n个城市,第i个城市有ai个人.Daene ...
- SpringAOP 使用注解的简单使用
1. 导入jar包 /SpringAOPmy/lib/com.springsource.net.sf.cglib-2.2.0.jar/SpringAOPmy/lib/com.springsource. ...
- ios系统web(微信公众号)开发遇到的问题及解决方案
1.1. 页面滚动不流畅(2017-09-25) 现象: 网页竖向滚动或横向滚动不流畅. 解决方案: 为滚动元素添加css样式: -webkit-overflow-scrolling: touch; ...
- 当DIV内出现滚动条,fixed实效怎么办?
sticky 盒位置根据正常流计算(这称为正常流动中的位置),然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位.在所有情况下( ...
- discuz伪静态问题(简单)
提前声明一下我用的是宝塔面板.Linux系统.Nginx Web Server.经过一上午的摸索(我很菜了),终于在一个很无语的地方成功搞了伪静态1.2.点击查看当前的 Rewrite 规则3.我的是 ...
- 一、SAP中添加一个模块到收藏夹后,显示事务代码
一.在SAP中,如果添加一个模块到收藏夹,默认是看不到事务代码的,如图: 二.我们在附件->设置中勾选显示技术名称 三.保存之后,就会显示出事务代码,如图所示: 不忘初心,如果您认为这篇文章有价 ...
- Linux 压缩解压操作
Linux 压缩解压操作 Linux解压文件到指定目录 tar在Linux上是常用的打包.压缩.加压缩工具,他的参数很多,折里仅仅列举常用的压缩与解压缩参数 参数:-c :create 建立压缩档案的 ...
- 用Python读取一个文本文件并统计词频
刚刚在写文章时360浏览器崩溃了,结果内容还是找回来了,感谢博客园的自动保存功能!!! ------------恢复内容开始------------ 最近在学习Python,自己写了一个小程序,可以从 ...
- vue项目配置多入口多出口【转载】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/localhost_1314/article ...