给你两个字符串 haystack
和 needle
,请你在 haystack
字符串中找出 needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle
不是 haystack
的一部分,则返回 -1
。
示例 1:
输入:haystack = "sadbutsad", needle = "sad" 输出:0 解释:"sad" 在下标 0 和 6 处匹配。 第一个匹配项的下标是 0 ,所以返回 0 。
示例 2:
输入:haystack = "leetcode", needle = "leeto" 输出:-1 解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。
public class title28 {
public static void main(String[] args) {
String haystack = "mississippi";
String needle = "issip";
int result = strStr(haystack, needle);
System.out.println(result);
}
public static int strStr(String haystack, String needle) {
int j = 0;
int[] next;
next=getNext(needle); //先算模式串的next[]
//1.先判断是否匹配,再找下标
//i指向母串,j指向模式串
for (int i = 0; i < haystack.length(); i++) {
//1.不匹配
while (j>0 && haystack.charAt(i) != needle.charAt(j)) {
j = next[j-1];
}
//2.字符匹配
if (haystack.charAt(i) == needle.charAt(j)) {
j++;
}
if(j==needle.length()){
return i-needle.length()+1;
}
}
return -1;
}
public static int[] getNext(String s){
int j = 0;
int[] next=new int[s.length()];
next[0] = 0;
for(int i = 1; i < s.length(); i++) { // 注意i从1开始,这样才能和j比较
while (j >0 && s.charAt(i) != s.charAt(j)) {
// 处理前后缀不相同,回溯是个连续的过程,所以是while不是if,又因为j起始位置是0,不能再回溯,所以是j>=0
j = next[j-1]; // 向前回溯,回溯前一位的next中的位置
}
if (s.charAt(i) == s.charAt(j)){
// 找到相同的前后缀
j++; //最长相等前后缀长度加1
}
next[i] = j; // 将j(前缀的长度)赋给next[i],不管前后缀是否相同,都要存放
}
return next;
}
}