在“代码随想录”公众号刷题过程中发现其中Java语言的题解方法是在原字符串中增加空格的方式,但上一篇讲解kmp算法和c++及其他语言的题解中都使用“前缀表减1实现”,所以尝试自己写一下,其实原理是相通的,但是思路一致对于初次尝试系统刷题的同学来讲可能更好理解。
原文地址:代码随想录
代码内容已在leetcode编译通过。
题目:
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
输入: "abab"
输出: True
解释: 可由子字符串 "ab" 重复两次构成。
示例 2:
输入: "aba"
输出: False
示例 3:
输入: "abcabcabcabc"
输出: True
解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/repeated-substring-pattern
著作权归领扣网络所有。
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
输入: "abab"
输出: True
解释: 可由子字符串 "ab" 重复两次构成。
示例 2:
输入: "aba"
输出: False
示例 3:
输入: "abcabcabcabc"
输出: True
解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/repeated-substring-pattern
题解:
class Solution {
public void getNext(int[] next,String s){ //j为前缀末尾,i为后缀末尾
int j =-1; //前缀表统一减1
next[0]=j;
for(int i=1;i<s.length();i++){ //注意i从1开始
while(j>=0 && s.charAt(i)!=s.charAt(j+1)){ //前后缀不同
j=next[j]; //向前回退
}
if(s.charAt(i)==s.charAt(j+1)){
j++;
}
next[i]=j; //将j(前缀的长度)赋给next[i]
}
}
public boolean repeatedSubstringPattern(String s) {
if(s.length()==0){
return false;
}
int len=s.length();
int[] next=new int[len];
getNext(next,s);
//最后判断是否是重复的子字符串,这里next[len]即代表next数组末尾的值
if(next[len-1]!=-1&&len%(len-(next[len-1]+1))==0){
return true;
}
return false;
}
}