KMP
前缀不包含最后一个字母,后缀不包括第一个字母。
28. 实现 strStr()
题目链接/文章讲解/视频讲解:代码随想录
给定一个非空的字符串
s
,检查是否可以通过由它的一个子串重复多次构成。
分析及思路
我们直接KMP匹配
代码及注释
int* getNext(char* s){
// 计算字符串长度
int s_len = strlen(s);
// 分配内存给next数组
int* next = (int*)malloc(sizeof(int)*s_len);
int j = 0;
next[0] = 0;
// 构建next数组
for(int i = 1;i < s_len;i++){
while( (j != 0) && (s[j] != s[i]) )
j = next[j-1];
if(s[j] == s[i])
j++;
next[i] = j;
}
// 返回next数组
return next;
}
int strStr(char* haystack, char* needle) {
// 获取needle的next数组
int* next = getNext(needle);
// 计算字符串长度
int haystack_len = strlen(haystack);
int needle_len = strlen(needle);
int number;
int j = 0;
int i = 0;
// 遍历haystack字符串
for(;i < haystack_len;i++){
// 使用KMP算法进行匹配
while(haystack[i] != needle[j]&&j != 0){
j = next[j-1];
}
if(haystack[i] == needle[j]){
j++;
}
if(j==needle_len)
return (i - needle_len + 1);
}
if(j==needle_len)
return (haystack_len - needle_len);
return -1;
}
459.重复的子字符串
题目链接/文章讲解/视频讲解:代码随想录
给定一个非空的字符串
s
,检查是否可以通过由它的一个子串重复多次构成。
KMP解法
分析及思路
这个题难理解,找最长相等前后缀,与总的字符串的差值,它就是最小重复子串,若能被总字符串整除,则说明子串能构成该整个字符串。
代码及注释
int* getNext(char* s){
// 计算字符串长度
int s_len = strlen(s);
// 分配内存给next数组
int* next = (int*)malloc(sizeof(int)*s_len);
int j = 0;
next[0] = 0;
// 构建next数组
for(int i = 1;i < s_len;i++){
while( (j != 0) && (s[j] != s[i]) )
j = next[j-1];
if(s[j] == s[i])
j++;
next[i] = j;
}
return next;
}
bool repeatedSubstringPattern(char* s) {
// 获取字符串的next数组
int* next = getNext(s);
int s_len = strlen(s);
// 获取next数组的最后一个值
int con_next = next[s_len-1];
// 如果最后一个值为0,则不可能存在重复子字符串,返回false
if(con_next==0)
return false;
// 如果字符串长度能整除(s_len-(next[s_len-1])),则说明存在重复子字符串,返回true,否则返回false
if(s_len%(s_len-(next[s_len-1]))==0)
return true;
else
return false;
}