实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
示例 1:输入:haystack = "hello", needle = "ll"输出:2
示例 2:输入:haystack = "aaaaa", needle = "bba"输出:-1
解:方法一:
在这道题中,我们没有很想起数据机构中的KMP算法,直接用暴力解决法。这使得时间复杂度变高,容易超时。
class Solution {
public:
int strStr(string haystack, string needle) {
int n = haystack.size(), m = needle.size();
for (int i = 0; i <= n; i++) {
cout<<i<<endl;
bool flag = true;
for (int j = 0; j < m; j++) {
if (haystack[i + j] != needle[j]) {
flag = false;
break;
}
}
if (flag) {
return i;
}
}
return -1;
}
};
方法二:
KMP 要考虑前缀和后缀;匹配串数组,为了减少for循环和匹配字符串的时间。
如图:f配对不上时,开头ab可以补上。
这是你应该会疑惑怎么得数组,我们先讲一下什么前缀,什么是后缀。
For example:
我们举个例子说明:字符串 aabaaabaabaaab 的前缀为除最后一个字母的字符串aabaaabaabaaa,而后缀是除第一种字母的字符串abaaabaabaaab。
下面的定义数组:
当arr[0]时,它一定为0;
当arr[1]时,a没有前缀和后缀,这时为0;
当arr[2]时,aa前缀和后缀为a,这时为1;
依此后推。
定义它的代码为:
for(int i=1,j=0;i<m;i++){//m为匹配串的长度 s为匹配串
If(j>0&&s[i]!=s[j]){//可以换成while()
j=pi[j-1];
}
if(needle[i]==needle[j]){
j++;
}
pi[i]=j;//定义数组
}
这题代码如下:
class Solution {
public:
int strStr(string haystack, string needle) {
int n=haystack.size(),m=needle.size();
if(m==0)return 0;
vector<int> pi(m);
for(int i=1,j=0;i<m;i++){
while(j>0&&needle[i]!=needle[j]){//可以换成if更好理解
j=pi[j-1];
}
if(needle[i]==needle[j]){
j++;
}
pi[i]=j;//定义数组
}
for(int i=0,j=0;i<n;i++){
while(j>0&&haystack[i]!=needle[j]){
j=pi[j-1];
}
if(haystack[i]==needle[j]){
j++;
}
if(j==m){
return i-m+1;
}
}
return -1;
}
};