leetcode传送通道
前有穿着羊皮的狼,后有披着绿衣的中等题
首先是 KMP 算法
kmp核心:构建next数组
class Solution {
public int strStr(String haystack, String needle) {
// KMP算法
char[] cs = haystack.toCharArray(); // 数组定位相比String.charAt会更快
char[] cs2 = needle.toCharArray();
int[] next = new int[needle.length()];
getNext(next, cs2);
for (int i = 0, j = 0; i < cs.length; i++) {
while (j > 0 && cs[i] != cs2[j]) {
j = next[j];
}
if (cs[i] == cs2[j]) {
j++;
if (j == cs2.length) {
return i - j + 1;
}
}
}
return -1;
}
// 核心:构建next数组:存储当前位置之前字符串的最大相等前后缀长度【也是当前位置回溯时访问的数组下标】
// 比如 abcdabd 对应 -1,0,0,0,0,1,2, 第一个字符之前没有字符串,这里写为-1
private void getNext(int[] next, char[] cs) {
int j = -1; // 指向当前最大相等前缀的后一位置,也表示最长公共前后缀的长度
int i = 0; // 指向当前最大相等后缀后一位置
next[0] = -1; // -1, 0, ...前两位固定
while (i < cs.length - 1) {
if (j == -1 || cs[j] == cs[i]) {
i++;
j++;
next[i] = j;
} else {
j = next[j];
}
}
}
}
再来一个非KMP算法的解法
class Solution {
public int strStr(String haystack, String needle) {
if (!haystack.contains(needle)) {
return -1;
}
for (int i = 0; i <= haystack.length() - needle.length(); i++) {
if (needle.equals(haystack.substring(i, i + needle.length()))) {
return i;
}
}
return -1;
}
}
再来一个使用内置函数一行解决的版本
class Solution {
public int strStr(String haystack, String needle) {
return haystack.indexOf(needle);
}
}