代码随想录算法训练营第九天 |28. 找出字符串中第一个匹配项的下标、459. 重复的子字符串
KMP
- 前缀表中遇见冲突的时候要根据其回退
- 遇到冲突,移动到next数组前一位的位置。
28. 找出字符串中第一个匹配项的下标
题目链接:28. 找出字符串中第一个匹配项的下标
-
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要保证大于0,因为下面有取j-1作为数组下标的操作 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; // search部分 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; } };
459. 重复的子字符串
题目链接:459. 重复的子字符串
-
class Solution { public: bool repeatedSubstringPattern(string s) { int len = s.size(); for(int i = 1 ; i*2 <= len; i++) { if(len % i == 0) { bool match = true; for(int j = i; j < len; j++) { if(s[j] != s[j - i]) { match = false; break; } } if(match) { return true; } } } return false; } }; -
暴力法:
- 如果要重复必须满足s[j] == s[j - i]
-
KMP:
-
移动匹配
- 当然,我们在判断 s + s 拼接的字符串里是否出现一个s的的时候,要刨除 s + s 的首字符和尾字符,这样避免在s+s中搜索出原来的s,我们要搜索的是中间拼接出来的s。