class Solution {
public int strStr(String haystack, String needle) {
if (haystack == null || needle == null || needle.length() < 1 || haystack.length() < needle.length()) {
return -1;
}
int[] next=getNext(needle.toCharArray());
int i=0; //指向匹配数组的指针
int j=0;//指向被匹配数组的指针
int res=-1;
while(i<haystack.length()&&j<needle.length()){
//如果两个字符相等
if(haystack.charAt(i)==needle.charAt(j)){
i++;
j++;
}else if(j>0){//如果还能往左跳
j=next[j];
}else{
//如果到了next数组0位置则说明没有可以匹配的位置了
i++;
}
//子串已经到达最后了,代表父串中已经出现了一次
//i和j其实最后都进行了额外的一次++操作
}
return j == needle.length()? i -j: -1;
}
public static int[] getNext(char[] str) {
if (str.length == 1) {
return new int[]{-1};
}
int[] next = new int[str.length];
next[0] = -1;
next[1] = 0;
// i: next数组的位置
int i = 2;
// j: 要和next[i-1]比较的位置,最长的可能的公共前缀的位置
int j = 0;
while (i < next.length) {
if (str[i - 1] == str[j]) {
next[i++] = ++j;//如j匹配上了则对于此刻i的最大前缀长度加一同时跳到下一个i位置
} else if (j > 0) {
// 当前跳到j位置的字符,和i-1位置的字符配不上,则j继续向前跳,直到跳到最开始0位置,或者匹配上
j = next[j];
} else {
//j跳到头也没匹配上,i++到下一个位置
next[i++] = 0;
}
}
return next;
}
}