kmp算法时间复杂度难以理解之处的一些胡诌

(转载于笨人的微信公众号)
这是笨人在研究kmp算法时间复杂度时想到的一种(非常乱来非常没有根据)的理解方法,大家能懂个大概意思就好。理解本文需要一些热学方面对于信息熵的知识,以及对kmp算法的基础认识。

Kmp算法是一种匹配字符串的方法,目的是通过内蕴于需要匹配的子串P自身的特征,快速寻找其在主串S中的位置。

KMP算法的时间复杂度分为两部分,第一部分是构建子串的特征向量(或者叫next数组,具体好像也有很多种说法傻傻分不清)的时间复杂度,另外一部分是进行匹配时的时间复杂度。具体进行细分,构建子串的时间复杂度=单方向遍历每个字母*对每个字母进行匹配的回溯;进行匹配的时间复杂度=遍历S串中的每个字母(每个字母只遍历一次)*对每个字母进行匹配回溯。

显然,单方向遍历的时间复杂度是正比于串长度M与N的。KMP算法整体的时间复杂度就是O(m+n)。关键在于,为什么回溯的时间复杂度是随机常量类型(瞎诌的词,也就是O(1)),或者说,回溯的次数与我开始回溯的位置没有关系(无论我从多远开始回溯)。

我们把视角回到热学。在计算微观熵时有一种概念叫做“微观状态数”,或者“热力学概率”,表示热力学系统中的所有可能微观状态。令其为W,则熵正比于lnW,信息缺失正比于-lnW。

下面我们取next数组中的n[k]作为研究对象,n[k]的值必然小于k,但是具体是几我们却不知道,那么这个值就是我们的随机变量,有k-1种微观状态数。在不知道具体是几时,信息熵为ln(k),如果我们已经确定了这个值,则其信息正比于ln(k)。

在回溯时(首先就构建next数组中的回溯说),每一步向前的回溯(k=n[k-1]),都会将k进行一个更新,而k被更新的位置的n[k]是一个已知的值,从中获得ln(n[k])的信息。

我们的目的是要得到回溯开始位置i0的next值,需要获取ln(i0)的信息,而我们每次单步回溯可以获得ln(n[k])的信息。对于完全随机的情况,n[k]/i0的平均值是1/2,则信息差δI=ln(i0)-ln(n[k]),而这个δI对应的应该是一个常量(ln(2))。那么常量步的回溯是很容易把这部分信息补全的(随随便便再来一个k>2就够了)

或者说,对于n[k-1]/k是一个固定比例η,单次回溯中的步数最大正比于ln(η),但总获得信息则正比于

(凶猛近似)

因此只要完成正比于(ln(η)/ln(i0))^2步的k=n[k-1]就大概可以把信息补全了,但是这个数怎么看都是小于1的。至此证明了回溯的数量级的确是常量。对于与S串匹配时也是同理。

(思路非常意识流并且一如既往地运用了不严谨迁移的思维,看个乐呵帮助理解)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值