Come from : [https://leetcode-cn.com/problems/implement-strstr/]
28. Implement strStr(
1.Question
Implement strStr().
Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
Example 1 :
Input: haystack = "hello", needle = "ll"
Output: 2
Example 2 :
Input: haystack = "aaaaa", needle = "bba"
Output: -1
Clarification:
What should we return when needle is an empty string? This is a great question to ask during an interview.
For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C’s strstr() and Java’s indexOf().
2.Answer
easy类型题目。。。
AC代码如下(定义两个辅助指针变量,暴力解法):
class Solution {
public:
int strStr(string haystack, string needle) {
if(needle.size() == 0) return 0;
if(haystack.size() == 0) return -1;
int h_pointer = 0;
int n_pointer = 0;
while(h_pointer < haystack.size())
{
if(haystack[h_pointer] == needle[n_pointer])
{
++h_pointer;
++n_pointer;
if(n_pointer == needle.size())
{
return h_pointer-n_pointer;
}
}
else
{
h_pointer = h_pointer - n_pointer + 1;
n_pointer = 0;
}
}
return -1;
}
};
3.大神解答
方法1:速度排名第一(KMP算法 时间复杂度O(M+N))
关于KMP算法的介绍见:1. kmp算法1
2. kmp算法2
class Solution {
vector<int> next;
inline void updateNextTable(string &needle){
next.resize(needle.size());
next[0] = -1;
if(next.size()>1){
next[1] = 0;
}
int pi = 1;
int pj = 0;
while(pi < next.size()-1)
{
if(pj == -1 || needle[pi] == needle[pj] ){
next[++pi] = ++pj;
}
else{
pj = next[pj];
}
}
}
public:
int strStr(string haystack, string needle) {//KMP
if(needle.size() == 0){
return 0;
}
updateNextTable(needle);
if(haystack.size() == 0){
return -1;
}
int pi=0,pj=0;
while(pi<haystack.size() && pj<(int)needle.size())
{
if(pj == -1 || haystack[pi] ==needle[pj] ){
++pi;
++pj;
}
else{
pj = next[pj];
}
}
if(pj == needle.size())
{
return pi - pj;
}
return -1;
}
};
方法2:sunday算法(时间复杂度 最坏为O(M*N) 平均复杂度为O(N))
字符串匹配——Sunday算法
class Solution {
public:
int strStr(string haystack, string needle) {
if(needle.empty())
return 0;
int slen=haystack.size();
int tlen=needle.size();
int i=0,j=0;//i指向源串首位 j指向子串首位
int k;
int m=tlen;//第一次匹配时 源串中参与匹配的元素的下一位
for(;i<slen;)
{
if(haystack[i]!=needle[j])
{
for(k=tlen-1;k>=0;k--)//遍历查找此时子串与源串[i+tlen+1]相等的最右位置
{
if(needle[k]==haystack[m])
break;
}
i=m-k;//i为下一次匹配源串开始首位 Sunday算法核心:最大限度跳过相同元素
j=0;//j依然为子串首位
m=i+tlen;//m为下一次参与匹配的源串最后一位元素的下一位
if(m>slen)//当下一次参与匹配的源串字数的最后一位的下一位超过源串长度时
return -1;
}
else
{
if(j==tlen-1)//若j为子串末位 匹配成功 返回源串此时匹配首位
return i-j;
i++;
j++;
}
}
return -1;//当超过源串长度时
}
};
作者:2227
链接:https://leetcode-cn.com/problems/two-sum/solution/c5chong-jie-fa-ku-han-shu-bfkmpbmsunday-by-2227/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
4.我的收获
字符串匹配算法。。。
2019/7/6 胡云层 于南京 116