题目链接🔗:
28. 实现 strStr()
459.重复的子字符串
28. 实现 strStr()
经典的 KMP,构建一个 next 数组,数组下标的值是根据对应字符串中对应下标字符能构成的后缀字符串和能和以首个字符构成的前缀字符串相同的最长数值。
int next[n];
next[0] = -1;
int i = 1, j = -1;
// 使用减一的前缀表 ,注意比较的是i 和 j + 1
for (i = 1; i < n; i++) {
while (j >= 0 && s[i] != s[j + 1] ) {
j = next[j];
}
if (s[i] == s[j + 1] ) {
j++;
}
next[i] = j;
}
j = -1;
for ( i = 0; i < haystack.length(); i++) {
while (j >= 0 && haystack.charAt(i) != needle.charAt(j + 1) {
j = next[j];
}
if (haystack.charAt(i) == needle.charAt(j + 1) {
j++;
}
if ( j ==needle.length -1 ) {
return (i - needle.length() + 1);
}
}
459.重复的子字符串
同样使用 KMP,做法有两种。
一种是将字符串复制后两个相同的字符串进行拼接,找到一个新的原本的字符串,同时要注意找到的不能是原来的两个字符串中的字符串。
第二种方法是通过 next 数组,得到next 的最后一个元素的最大前后缀重复字符数,用字符串总长度作差,假如这个差可以被字符串整除就说明这个字符串是由重复的子字符串组成的。
注意的是选择使用减一的前缀表需要作差的时候额外减一。
总结
KMP:能理解,但是自己写的时候老是出错,还是老老实实背下来吧。