KMP算法
本题有2种解法:
1. 滑动窗口法
public int strStr(String haystack, String needle) {
//时间复杂度:O(m*n)
for (int i = 0; i <= haystack.length() - needle.length(); i++) {
int top = i;
int down = 0;
while (down < needle.length() && haystack.charAt(top) == needle.charAt(down)) {
top++;
down++;
}
if (down == needle.length()) return i;
}
return -1;
}
2. KMP算法
前缀表的意义:跳过前面重复的前缀,直接从前缀后面进行匹配
//构建前缀表
public void getNext(int[] next, String s) {
int j = 0;
for (int i = 1; i < next.length; i++) {
//找到相匹配的前缀和后缀(定住后缀的i,找到j相匹配的前缀)
while (j > 0 && s.charAt(i) != s.charAt(j)) {
// 易错点:不能用j--,因为上一个字符相等会跳出循环,得出错误的结果
j = next[j - 1];
}
if (s.charAt(i) == s.charAt(j)) {
j++;
}
//前缀表赋值
next[i] = j;
}
}
//
public int strStr(String haystack, String needle) {
if (needle.length() == 0) {
return 0;
}
// 用来比较的短子串构建next数组
int[] next = new int[needle.length()];
getNext(next, needle);
int j = 0;
for (int i = 0; i < haystack.length(); i++) {
// 找到相匹配的母串后缀和字串前缀(定住母串的i,找到子串j相匹配的前缀)
while (j > 0 && needle.charAt(j) != haystack.charAt(i)) {
// 易错点:不能用j--,因为上一个字符相等会跳出循环,得出错误的结果
j = next[j - 1];
}
if (needle.charAt(j) == haystack.charAt(i)) {
j++;
}
if (j == needle.length()) {
return i - needle.length() + 1;
}
}
return -1;
}