实现的代码如下:
这是一道典型的字符串匹配题……直接用KMP算法然后就过了
1 | class Solution { |
看这里⤵️
首先我们要搞清楚next数组的含义:
next数组的值是代表着字符串的前缀与后缀相同的最大长度,(不能包括自身)
1 | while(k>0&&s[k]!=s[i]) |
举个栗子,给了一个模式串“ABABAA”,我们得到的next数组的值应该是这样的
next[0]=0;
next[1]=0;
next[2]=1;
next[3]=2;
next[4]=3;
next[5]=1;
① :
next[0],next[1]我们可以手动模拟代码,然后很简单得出答案;
② :
那么如何求next[2]呢?此时的s[2]=’A’,s[0]=’A’,两个相等,所以next[2]=k++=1;如果这里s[2]!=’A’,不相等的话就是next[2]=0;
③ :
现在我们是已知next[0]=0,next[1]=0.next[2]=1的情况下了,然后现在要求next[3],怎么办呢?
④ :
接着执行next[3]的计算,首先while循环里面只有一个条件满足k=1>0,而s[1]=s[3]=‘B’,所以我们直接让k++,next[3]=2;
⑤ :
接着我们计算next[4],现在的k=2,并且s[2]=’A’,s[i]=s[4]=’A’,不满足while的2个条件,所以又要让k++,则next[4]=3;
⑥ :
接着计算next[5],现在的k=3,s[3]=’B’,s[5]=’A’,两者不相同,那么执行while循环,接下来k的值就应该为next[k-1]了,为什么?
现在我给出两个字符串,一个是原来的模式串”ABABAA“,一个是m串”ABABAB“;我就将最后的s[5]由‘A’ 字符变成了‘B’,如果是‘B’字符的话,那么k又要加一,则next[5]=4;
现在按照真实情况来,为什么要k=next[k-1];是因为如果第下标为k的这个s[k]字符和现在的s[i]不同,我们就要看s[i]是不是能与s[k-1],也就是k前一位的字符匹配,如果能,在当前的k值的基础上加上一个1作为s[i]的next值,(这里的k值实际上是next[k+1],此时k位置后面的一个next数组的值)如果还不相同,继续让k往前一位挪,直到最后没有匹配的那么next[5]为0,途中有匹配的话就按照k位置的上一个位置的next数组的值加一个1。
最后结束next数组的计算。
说句实话,这个next数组的计算为什么要这样,真的是有点只可意会不可言传的意思,你要真的自己用自己的方法理解了才能做好题……此外还有一些推导公式,为什么在KMP算法中要让j回溯到next[j-1]的位置,如果不理解的可以去百度一下,看看这些知识点……