[Leetcode] 28. 找出字符串中第一个匹配项的下标
题目链接:28. 找出字符串中第一个匹配项的下标
KMP:
KMP
主要应用在字符串匹配上。
KMP
的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。
我们使用的方法是0开始的。next[i]
存的是以 i
为结尾的最长前后缀相等的长度。
匹配流程:
这里假设主串为 s
,模式串(子串)为 t
, 当 s[i]
和 t[j]
不匹配时,因为前面我们已经匹配过了,那么就回到 j - 1
的最长相等前后缀的强度,因为数组从0开始的,那么这个长度的值就是我们下一个要匹配的那一位。
这里就不详细赘述了,详情看链接。
代码(Java):
public void getNext(int[] next, String s) {
// j 是前缀的末尾 i 是后缀的末尾
int j = 0;
next[0] = j;
// 这里求next数组的方法是,如果haystack[i] != needle[j]
// 那么 j 就跳到next[j - 1],因为我这里next数组存的是最长公共前后缀的长度,那么就跳到前面匹配过的那里
for(int i = 1; i < s.length(); i ++) {
while(j > 0 && s.charAt(i) != s.charAt(j)) j = next[j - 1];
if(s.charAt(i) == s.charAt(j)) j ++;
next[i] = j;
}
}
public int strStr(String haystack, String needle) {
if(haystack == null || needle == null) return -1;
// haystack是文本串 needle是模式串 那么我们求模式串的next数组
int[] next = new int[needle.length()];
getNext(next, needle);
for(int i = 0, j = 0; i < haystack.length(); i ++) {
while(j > 0 && haystack.charAt(i) != needle.charAt(j)) j = next[j - 1];
if(haystack.charAt(i) == needle.charAt(j)) {
j ++;
}
if(j == needle.length()) return i - j + 1;
}
return -1;
}