KMP算法
参考https://www.bilibili.com/video/BV19Q4y1c7ko?t=3967.9
看了好多文章和视频,解法各种各样,我真的是看晕了,大多数将 nxt 数组的构建都讲太含糊,很难理解KMP算法的核心。这里推荐看看左神的讲解,相当细致,看完后茅塞顿开。
这里以atcoder430的E题为例,我看了挺多题解,好多都是用字符串哈希写的,这里提供一个KMP算法的思路。
查看代码#include<bits/stdc++.h> using namespace std; const int N = 2e6 + 5; int nxt[N]; void getNxt(const string& s){ nxt[0] = -1; nxt[1] = 0; int j = 2, cn = 0; while(j <= s.length()){ if(s[j - 1] == s[cn]){ nxt[j++] = ++cn; }else if(cn > 0){ cn = nxt[cn]; }else{ nxt[j++] = 0; } } return ; } void solve(){ string a, b; cin >> a >> b; a = a + a; int len1 = a.length(), len2 = b.length(); getNxt(b); //KMP算法 int i = 0, j = 0; while(i < len1){ if(a[i] == b[j]){ i++, j++; }else if(j > 0){ j = nxt[j]; }else{ i++; } if(j == len2){ cout << i - j << endl; return ; } } cout << -1 << endl; return ; }字符串A每次把第一个字符移动到末尾,对于字符串B来说就是不断向右移动找到与之匹配的字符串A的位置,这不就是KMP算法的过程吗,我们先构建nxe数组,记录字符串B每个字符的最长公共前后缀,执行KMP算法,移动 i 与 j,直至匹配成功后退出。

浙公网安备 33010602011771号