被KMP算法折磨了。
花了半天画了个图,KMP代码倒是记住了,但是还有有些地方没理解。
代码如下:
class Solution {
public:
void getnext(int* next,const string &s)
{
next[0]=0;
int j =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 - needle.size() + 1);
}
}
return -1;
}
};
这题目可以用KMP来解,也可以用一种非常有趣的方法来解。就是移动匹配的方法。
因为本题是检查一个字符串是否可以由自己的子串重复构成,那我们可以直接
将这个字符串复制一遍,然后放在自己的后面,将首字符和尾字符删除了。
然后在从新的字符串中去查找老字符串,如果能查找到,说明有子串可以重复构成该字符串。
代码如下:
class Solution {
public:
bool repeatedSubstringPattern(string s) {
string t = s + s;
t.erase(t.begin()); t.erase(t.end() - 1); // 掐头去尾
if (t.find(s) != std::string::npos) return true; // r
return false;
}
};
字符串总结:
想想双指针法,想想可不可以局部反转和整体反转,然后遇到字符串匹配问题的时候看看能不能使用KMP算法。
双指针总结:
双指针的方式非常多。快慢指针,左右指针,多思考。