字符串
459. 重复的子字符串
思考
判断一个字符串s
是否包含子串,可以将2个s
首尾相连,组合成t=s+s
(剔除首尾字符),如果字符串s
存在字串,那么t
一定存在字符串s
。
例如,一个字符串由abab
组成,那么组合后是abababab
,去掉首尾之后bababa
,那么字符串中依然存在一个字符串abab
。
func repeatedSubstringPattern(s string) bool {
t := s + s
return strings.Contains(t[1:len(t)-1], s)
}
进阶
可以考虑使用KMP算法实现,重复字串是最长相同前后缀不包含的那部分
func repeatedSubstringPattern(s string) bool {
n := len(s)
next := make([]int, n)
j := -1
next[0] = j
for i := 1; i < n; i++ {
for j >= 0 && s[i] != s[j+1] {
j = next[j]
}
if s[i] == s[j+1] {
j++
}
next[i] = j
}
if next[n-1] != -1 && n%(n-(next[n-1]+1)) == 0 {
return true
}
return false
}
总结
使用next数组元素-1的方式实现,next[n-1]+1
是最长相同前后缀的长度,n-(next[n-1]+1)
就是最长相同前后缀不包含的子串, 如果能被长度n整除,那么就可以断定字符串是由这个字串重复构成。