KMP算法
思想
-
要解决的问题?
1.字符串匹配算法,解决abc123里面有没有123
2.题目链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/
https://leetcode.cn/problems/repeated-substring-pattern/description/
-
时间复杂度 O(N)
(暴力时间复杂度是O(N * M))
-
next[]数组是什么
1.存放模式数组(短数组,123)的前缀,后缀最长相等长度
2.比如aabaab的next[] = {-1,0,1,0,1,2}
3.next数组前两个人为规定-1,0,后面的值是该下标之前的(不包括该下标)字符串前缀,后缀最长相等长度
-
前缀:一定包含第一个字符,一定不包含最后一个字符
-
后缀:一定包含最后一个字符,一定不包含第一个字符
板子
//KMP实现过程
public static int getIndexOf(String s1,String s2) {
if(s1 == null || s2 == null || s1.length() < s2.length())
return -1;
char[] str1 = s1.toCharArray();//文本数组 长数组
char[] str2 = s2.toCharArray();//模式数组 短数组
int x = 0;//第一个圈
int y = 0;//第二个圈
int[] next = getNextArray(str2);//next数组
while(x < s1.length() && y < s2.length()) {
//字符相等,往后匹配
if(str1[x] == str2[y]) {
x++;
y++;
}
else if(next[y] == -1) { // y == 0
x++;
}
else {
y = next[y];//向右推的过程
}
}
return y == s2.length() ? x - y : -1; //x越界则没有匹配到,y越界才有下标
}
//求next数组过程
public static int[] getNextArray(char[]str2) {
if(str2.length == 1) {
return new int[] {-1};
}
int next[] = new int[str2.length];
next[0] = -1;
next[1] = 0;
int i = 2;//next数组的下标
int cn = 0;
while(i < next.length) {
if(str2[i - 1] == str2[cn]) { //配成功
next[i++] = ++cn;
}
else if(cn > 0) {
cn = next[cn];
}
else {
next[i++] = 0;
}
}
return next;
}