1、KMP算法概念和解决问题
KMP 算法是 D.E.Knuth
、J,H,Morris
和 V.R.Pratt
三位共同提出的,称之为 Knuth-Morria-Pratt
算法,简称 KMP 算法。
该算法主要是消除了主串指针的回溯,从而使算法效率有了某种程度的提高。
适合在有重复比较的问题的中使用,可以减少重复比较的次数,从而优化时间复杂度
2、KMP算法
例如有两个字符串P:{a,b,c,d,e,f,g,e,f}
和Q:{e,f,g,e,f}
,从P中找出Q的首次出现的位置(P的下标)。
暴力解题思路是通过双指针法,依次比较PQ中元素是否相同。
但是这样方法会有很多次重复的计算。举一个极端的例子就是P为{a,a,a,a,a,a,a,a,a,b}
,Q为{a,a,a,a,b}
。这样的情况下使用暴力的双指针的方法就会每次都重复判断a,a,a,a
。使用KMP算法就是用来优化样重复比较的过程。
KMP算法中有个很重要的概念叫做前缀表的概念,就是计算出Q字符串的各个长度时它的前后一样的元素个数
比如:Q:{a,a,a,a,b}
那边Q的前缀表计算过程为
Q长度为1时是{a}
,前缀没有元素,只有他本身,所以设定为-1
Q长度为2时是{a,a}
,前缀为{a}
,所以前缀表为1
Q长度为3时是{a,a,a}
,前缀为{a,a}
,所以前缀表是2
Q长度为4时是{a,a,a,a}
,前缀为{a,a,a}
,所以前缀表是3
Q长度为5时是{a,a,a,a,b}
,前缀为{a,a,a,a}
,所以前缀表是4
所以Q的前缀表为{-1,1,2,3,4}
计算出Q的前缀表之后,在和P中的元素比较的时候,如果不同,则可以直接将P中的指针移动到Q的前缀表对应数字的P的下标处。
例如:P的指针从0的位置比较到4的位置(黑色i的位置),比较出a不等于b,此时,i不用继续从1的位置再次开始比较,而是直接从前缀表中对应的4-1的位置开始比较。