459. 重复的子字符串
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
输入: "abab"
输出: True
解释: 可由子字符串 "ab" 重复两次构成。
示例 2:
输入: "aba"
输出: False
示例 3:
输入: "abcabcabcabc"
输出: True
解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)
题解:
首先需要充分理解题意,即所谓重复字符串有怎样的性质呢?
我们不妨设重复字符串为s,设其可以由子串s1重复多次得到。
1.显而易见的是,s一定是s1成倍数关系。
2.s1起点一定为s的头部位置,或可以平移到此位置。
3.s[i] == s[i-n]成立。
对于性质1不再解释。
对于性质2:
我们可以反证,即如果s1起点和s头部位置对应的字符不同时,由于性质1我们可知最后剩余的一部分就是s头部的几个位置,而由于s1与其不同所以必定不可能组成重复字符串s。
对于性质3:
可以由性质1发现s可以分成n个s1,因此他们可以理解成为周期性排列。
代码:
bool repeatedSubstringPattern(char * s){
for(int i=0;i*2<strlen(s);i++)
//为了避免出现i<strlen(s)/2,因为这样的话如果s长度为1,那么1/2为0了,所以尽量不要出现除法
{
int n = i+1;//起点已固定,我们遍历i是为了找终点
bool flag = 0;//使用布尔类型做标志量更易
if(strlen(s)%n!=0)
{
continue;
}
for(int j=i+1;j<strlen(s);j++)//此为验证我们找的子串是不是可以满足题意
{
if(s[j]!=s[j-n])
{
flag = 0;
break;
}
else
{
flag = 1;
}
}
if(flag==1)
{
return 1;
}
}
return 0;
}