小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
459. 重复的子字符串
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
- 示例 1:
输入: "abab"
输出: True
解释: 可由子字符串 "ab" 重复两次构成。
- 示例 2:
输入: "aba"
输出: False
- 示例 3:
输入: "abcabcabcabc"
输出: True
解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)
解题思路
KMP 算法是 D.E.Knuth、J,H,Morris 和 V.R.Pratt共同提出的,称之为 Knuth-Morria-Pratt 算法,简称 KMP 算法。该算法相对于 Brute-Force(暴力)算法有比较大的改进,主要是消除了主串指针的回溯,从而使算法效率有了某种程度的提高。
主串指针的回溯:txt = "aaacaaab" pat = "aaab",例如txt和pat进行匹配,在匹配至第4位时,出现了不匹配,那么txt指针就需要回溯到第二位,pat指针回溯到第一位,重新进行匹配
kmp算法匹配:next代表最长公共前缀和后缀的匹配长度
- 当i与k不匹配的时候,可以通过next数组回退k指针进行匹配,而不需要像暴力法那样,回退到第一位进行匹配
- 如果k==0了,代表当前情况下不存前缀和后缀不存在公共部分
代码
class Solution {
public boolean repeatedSubstringPattern(String s) {
int n=s.length(),k=0;
int[] next=new int[n];
for(int i=1;i<n;i++)
{
while(k>0&&s.charAt(i)!=s.charAt(k))
k=next[k-1];
if(s.charAt(i)==s.charAt(k))
k++;
next[i]=k;
}
return next[n-1]!=0&&n%(n-next[n-1])==0;
}
}