问题描述:
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = "hello", needle = "ll"
输出: 2示例 2:
输入: haystack = "aaaaa", needle = "bba"
输出: -1说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
来源:力扣(LeetCode)
解决思路:
本题是查找文本串中模式串出现的第一个位置。
即:
1.判断模式串与文本串是否匹配。
2.返回模式串所在的位置。
而解决这种问题的典型解法就是KMP解法。
(1)KMP解法的第一步也是最重要的一步就是先求取模式串(needle)的next数组。
主要原理即:求取模式串的最长相等前后缀的长度。
主要有如下三步:
-
初始化
-
处理前后缀不相同的情况
-
处理前后缀相同的情况
getNext() 方法即为KMP算法获取next数组的方法。
(2)获取到next数组之后,用于做匹配。
遍历文本串,如果 s[i] 与 t[j + 1] 不相同,j就要从next数组里寻找下一个匹配的位置。
如果 s[i] 与 t[j + 1] 相同,那么i 和 j 同时向后移动。
如果j指向了模式串t的末尾,那么就说明模式串t完全匹配文本串s里的某个子串了。
本题要在文本串字符串中找出模式串出现的第一个位置 (从0开始),所以返回当前在文本串匹配模式串的位置i 减去 模式串的长度,就是文本串字符串中出现模式串的第一个位置。
Java代码:
class Solution {
public int strStr(String haystack, String needle) {
int n1 = haystack.length();
int n2 = needle.length();
if(n2 == 0) return 0;
int [] next = new int [n2];
getNext(next,needle,n2);
int index = -1;
for(int i=0;i<n1;i++){
while(index>=0 && haystack.charAt(i)!=needle.charAt(index+1)){
index = next[index];
}
if(haystack.charAt(i)==needle.charAt(index+1)){
index++;
}
if(index==n2-1){
return i-n2+1;
}
}
return -1;
}
public void getNext(int[] next,String s,int n){
int i,j;
j=-1;
next[0] = j;
for(i=1;i<n;i++){
while(j>=0 && s.charAt(i)!=s.charAt(j+1)){
j = next[j];
}
if(s.charAt(i)==s.charAt(j+1)){
j++;
}
next[i] = j;
}
}
}