给你两个字符串 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 。
提示:
1 <= haystack.length, needle.length <= 104
haystack
和needle
仅由小写英文字符组成
使用kmp算法,实话实说第一遍刷代码随想录,这个算法并没有完全理解,理解了80%左右。
最不理解的地方在:
先想暴力算法,每次匹配不成功时i都应该回到开始的地方+1;但kmp算法并没有,这一点我不是很理解,如果有懂得希望你能在评论区里给讲解一下(万分感谢);
解答:这个地方我的理解是:
例如
aaaaaaafa
aaaaaf
这个回退后其实是回到了最开始的地方+1;所以它有的时候不回去的原因是最大相等前后缀长度没达到最大,如果达到最大我们会发现会回到,这也是kmp简化比较的一部分
class Solution {
public:
void getnext(int *next,const string s){
int j=0;
next[0]=0;
for(int i=1;i<s.size();i++){
while(j>0&&s[i]!=s[j]){
j=next[j-1];
}
if(s[i]==s[j])j++;
next[i]=j;
}
}
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(j>0&&haystack[i]!=needle[j])j=next[j-1];
if(haystack[i]==needle[j])j++;
if(j==needle.size()){
return (i-j+1);
}
}
return -1;
}
};
给定一个非空的字符串 s
,检查是否可以通过由它的一个子串重复多次构成。
示例 1:
输入: s = "abab" 输出: true 解释: 可由子串 "ab" 重复两次构成。
示例 2:
输入: s = "aba" 输出: false
示例 3:
输入: s = "abcabcabcabc" 输出: true 解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)
提示:
1 <= s.length <= 104
s
由小写英文字母组成
利用最长相等前后缀来解决的,一刷随想录理论证明,等二刷再给出
class Solution {
public:
bool repeatedSubstringPattern(string s) {
if(s.size()==0)return false;
int j=0;
int next[s.size()];
next[0]=0;
for(int i=1;i<s.size();i++){
while(j>0&&s[i]!=s[j])j=next[j-1];
if(s[i]==s[j])j++;
next[i]=j;
}
if(next[s.size()-1]!=0&&s.size()%(s.size()-next[s.size()-1])==0)return true;
return false;
}
};