目录
问题描述:
给你两个字符串 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 。
实现代码与解析:
kmp算法:
class Solution {
public:
//求next数组
void getNext(int next[],const string& s)
{
int j=0;
next[0]=0;
for(int i=1;i<s.size();i++)
{
//回退
while(s[i]!=s[j]&&j>0)
{
j=next[j-1];
}
if(s[i]==s[j])
{
j++;
}
next[i]=j;//填写next数组
}
}
int strStr(string haystack, string needle)
{
if(needle.size()==0)
{
return 0;
}
int next[needle.size()];
getNext(next,needle);
int j=0;
for(int i=0;i<haystack.size();i++)
{
while(needle[j]!=haystack[i]&&j>0)
{
j=next[j-1];
}
if(needle[j]==haystack[i])
{
j++;
}
if(j==needle.size())
{
return(i-needle.size()+1);
}
}
return -1;
}
};
原理思路:
就是经典的kmp算法,建议先学习一下kmp算法代码原理,还是不太好理解的,尤其是对于求next数组时回退的理解,这里就不解释了,不好用文字描述。
复杂度分析:
-
时间复杂度:O(n+m)
-
空间复杂度:O(n)
暴力匹配法:
class Solution {
public:
int strStr(string haystack, string needle)
{
for(int i=0;i+needle.size()<=haystack.size();i++)
{ol flag=true;
for(
boint j=0;j<needle.size();j++)
{
if(haystack[i+j]!=needle[j])
{
flag=false;
break;
}
}
if(flag)
{
return i;
}
}
return -1;
}
};
原理思路:
直接暴力,双循环一个一个遍历,不匹配再向后移动一位,再次匹配,直到匹配成功,或则没有匹配的子串返回-1,但是要是串的长度很长的话,实在是太慢了,所以最好还是掌握kmp这个数据结构的经典算法。
复杂度分析:
-
时间复杂度:O(n*m)
-
空间复杂度:O(1)