KMP
454.四数相加II
题目要求:给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
class Solution {
public int strStr(String haystack, String needle) {
int[] next = getNext(needle);
int j = 0; // needle的指针
for (int i = 0; i < haystack.length(); i++) {
while (j > 0 && needle.charAt(j) != haystack.charAt(i)) {
// 不相等情况
j = next[j - 1];
}
if (needle.charAt(j) == haystack.charAt(i)) {
// 相等情况
j++;
}
if (j == needle.length()) {
return i - needle.length() + 1;
}
}
return -1;
}
/**求得前缀表
*/
public static int[] getNext(String s) {
// i表示的是后缀末尾位置,j表示前缀末尾位置
int j = 0;
int[] next = new int[s.length()];
next[0] = 0;
for (int i = 1; i < s.length(); i++) {
// 若前后缀不相等
while (j > 0 && s.charAt(j) != s.charAt(i))
j = next[j - 1];
// 若前后缀相等
if (s.charAt(j) == s.charAt(i))
j++;
// 给next数组赋值
next[i] = j;
}
return next;
}
}
所思所获
这是一道经典的KMP题目,这题我是直接看到视频,大概明白了next数组的作用,以及前缀表是用来回位的。还需要多刷刷KMP的题目才能通透。
在求前缀表的思路中,i和j的作用分别是:i表示的是后缀末尾位置,j表示前缀末尾位置。而j的回退思路我还不怎么懂原理。可能数学还不过关吧。KMP中的回退一是求前缀表的回退,二是求位置时的回退。这两处我是最不理解的