# KMP Algorithm *Knuth-Morris-Pratt Algorithm* Leetcode Problem: * [28. Implement strStr()](https://leetcode.com/problems/implement-strstr/) * [459. Repeated Substring Pattern](https://leetcode.com/problems/repeated-substring-pattern/) * [686. Repeated String Match](https://leetcode.com/problems/repeated-string-match/) #### c++ version: ```cpp vector<int> lps(n,0); for(int i=1,j=0;i<n;) { if(T[i]==T[j]) lps[i++]=++j; else if(j==0) i++; else j=lps[j-1]; } ``` #### python version ```python i,j, lps = 1,0, [0]*n while(i<n): if(needle[i]==needle[j]): j += 1 lps[i] = j i += 1 elif(j==0): i+=1 else: j = lps[j-1] ``` Then we can use lps as Failure Function to solve these problems: ### 28. Implement strStr() #### c++ version ```cpp class Solution { public: int strStr(string haystack, string needle) { int m = haystack.size(), n = needle.size(); if(n==0) return n; vector<int> lps(n,0); for(int i=1,j=0;i<n;) { if(needle[i]==needle[j]) lps[i++]=++j; else if(j==0) i++; else j=lps[j-1]; } for(int i=0,j=0;i<m;) { if(haystack[i]==needle[j]) { i++; j++; } if(j==n) { return i-j; } else if(i<m && haystack[i]!=needle[j]) { if(j==0) { i++; } else { j = lps[j-1]; } } } return -1; } }; ``` #### python version ```python class Solution: def strStr(self, haystack: str, needle: str) -> int: h,n = len(haystack),len(needle) if(n==0): return 0 if(h<n): return -1 i,j, lps = 1,0, [0]*n while(i<n): if(needle[i]==needle[j]): j += 1 lps[i] = j i += 1 elif(j==0): i+=1 else: j = lps[j-1] i,j = 0,0 while(i<h): if(haystack[i]==needle[j]): i+=1 j+=1 if(j==n): return i-j elif(i<h and haystack[i]!=needle[j]): if(j==0): i+=1 else: j = lps[j-1] return -1 ``` ### 459. Repeated Substring Pattern #### c++ version ```cpp class Solution { public: bool repeatedSubstringPattern(string s) { int n = s.size(); vector<int> lps(n,0); for(int i=1,j=0;i<n;) { if(s[i]==s[j]) lps[i++]=++j; else if(j==0) i++; else j=lps[j-1]; } return lps[n-1]&&(lps[n-1]%(n-lps[n-1])==0); } }; ``` #### python version ```python= class Solution: def repeatedSubstringPattern(self, s: str) -> bool: n = len(s) i,j,lps =1,0, [0]*n while(i<n): if(s[i]==s[j]): j += 1 lps[i] = j i += 1 elif(j==0): i += 1 else: j = lps[j-1] return ((lps[n-1]>0) and (lps[n-1]%(n-lps[n-1])==0)) ``` ### 686. Repeated String Match #### c++ version ```cpp class Solution { public: int repeatedStringMatch(string a, string b) { int anum = a.size(); int bnum = b.size(); vector<int> lps(bnum,0); for(int i=1,j=0;i<bnum;) { if(b[i]==b[j]) lps[i++] = ++j; else if(j==0) i++; else j = lps[j-1]; } for(int i=0,j=0;i<anum;) { if(b[j]==a[(i+j)%anum]) { j++; } if(j==bnum) { if((i+j)%anum==0) return (i+j)/anum; return (i+j)/anum+1; } else if(i<anum && b[j]!=a[(i+j)%anum]) { if(j==0) { i++; } else { i += (j-lps[j-1]); j = lps[j-1]; } } } return -1; } }; ``` #### python version ```python class Solution: def repeatedStringMatch(self, a: str, b: str) -> int: m,n = len(a),len(b) i,j,lps = 1,0,[0]*n while(i<n): if(b[i]==b[j]): j += 1 lps[i] = j i += 1 elif(j==0): i += 1 else: j = lps[j-1] i,j = 0,0 while(i<m): if(b[j]==a[(i+j)%m]): j+=1 if(j==n): if((i+j)%m==0): return (i+j)//m return ((i+j)//m)+1 elif(i<m and b[j]!=a[(i+j)%m]): if(j==0): i+=1 else: i+=(j-lps[j-1]) j = lps[j-1] return -1 ```