编号459:重复的子字符串
编号459:重复的子字符串
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
输入: "abab"
输出: True
解释: 可由子字符串 "ab" 重复两次构成。
示例 2:
输入: "aba"
输出: False
示例 3:
输入: "abcabcabcabc"
输出: True
解释: 可由子字符串 "abc" 重复四次构成。(或者子字符串 "abcabc" 重复两次构成。)
思路
方法1:
利用next数组来做匹配,当next[len-1]!=0 并且&& (len%(len - (next[len-1]))==0;说明该字符串有重复的子字符串
next[n-1] 表示原字符串减去子字符串的长度,len-next[n-1] 表示子字符串的长度,所以它是一定可以被len整除的
方法2:
首先利用两个字符串相加
去掉相加后字符串的首字符和尾字符后是否包含原字符。
代码
public class 重复的子字符串 {
public static void main(String[] args) {
String s = "aba";
int[] next = kmpNext(s);
String s1 = Arrays.toString(next);
System.out.println(s1);
boolean b = isRepateString(s, next);
System.out.println(b);
}
//如果next[len-1] != 0;说明该字符串有最长相同的前后缀
public static int[] kmpNext(String str2) {
char[] chars = str2.toCharArray();
int[] next = new int[str2.length()];
int i = 0;//表示后缀的下标
int j = 0;//表示前缀的下表
next[0] = 0;
for (i = 1; i < chars.length; i++) {
//当两个字符串不相等时
while (j > 0 && str2.charAt(i) != str2.charAt(j)) {
j = next[j - 1];
}
if (str2.charAt(i) == str2.charAt(j)) {
j++;
}
next[i] = j;
}
return next;
}
//利用next数组匹配 if( next[len-1] != 0 && (len%(len - (next[len-1]))==0) )
public static boolean isRepateString(String s, int [] next ){
if( s.length() == 0 || s.length() == 1){
return false;
}
char[] chars = s.toCharArray();
int len = s.length();
if( next[len-1] != 0 && (len%(len - (next[len-1]))==0) ){
return true;
}
return false;
}
}
//——————————————————方法二------------------
public static boolean isRepateString2(String s){
String str = s+s;
boolean flag = str.substring(1, str.length() - 1).contains(s);
if(flag){
return true;
}else
return false;
}

浙公网安备 33010602011771号