今天主要复习了Kmp算法,第一题是经典的kmp题目,还是比较简单,第二题较难。理解不是很好。
第一题:
经典的kmp算法(时间复杂度O(M+N))不多说,或者使用时间复杂度为O(n^2)的双层for循环进行遍历。
kmp算法:
class Solution {
public:
char* getnext(string zichuan){
// 初始化next数组;
const int a = zichuan.length();
char* next = (char*)malloc(a*sizeof(char));
memset(next,0,a);
next[0]=0;
int preindex = 0;
int i=1;
while(i<a){
if(zichuan[i] == zichuan[preindex]){
preindex+=1;
next[i]=preindex;
i+=1;
}else{
if(preindex == 0){
next[i]=0;
i+=1;
}else{
preindex = next[preindex-1];
}
}
}
return next;
}
int strStr(string haystack, string needle) {
char* next = getnext(needle);
for(int i=0;i<needle.length();i++){
cout<<next[i]<<endl;
}
int ziindex=0;
int result =0;
for(int i=0;i<haystack.length();i++){
if(haystack[i]==needle[ziindex]){
if(ziindex == needle.length()-1){
cout<<i<<" "<<ziindex<<" "<<needle.length();
result=i-ziindex;
return result;
}
ziindex++;
}else{
if (ziindex == 0) {
continue;
}else {
ziindex = next[ziindex - 1];
i -= 1;
}
}
}
return -1;
}
};
第二题:
这道题的解法有三种思路
1.暴力解法(双层for循环第一层进行遍历字串,第二层进行字串匹配)
2.移动匹配
思路:
将字符串变成两份加在一起,,然后删除头尾字符,然后用find函数去匹配是否有和s字符串相等的存在,有则返回true,没有则返回false。
3.kmp算法
void getNext (int* next, const string& s){
next[0] = -1;
int j = -1;
for(int i = 1;i < s.size(); i++){
while(j >= 0 && s[i] != s[j + 1]) {
j = next[j];
}
if(s[i] == s[j + 1]) {
j++;
}
next[i] = j;
}
}
bool repeatedSubstringPattern (string s) {
if (s.size() == 0) {
return false;
}
int next[s.size()];
getNext(next, s);
int len = s.size();
if (next[len - 1] != -1 && len % (len - (next[len - 1] + 1)) == 0) {
return true;
}
return false;
}
思路:
总结:
今天复习了kmp算法,第二题没想出来如何得到最小字符串,题解的方法很便利,又很巧妙,就是我想不出来。还要继续加油!