算法练习-第十天【字符串】

字符串

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整除,那么就可以断定字符串是由这个字串重复构成。

posted @ 2022-10-07 23:24  neil_liu  阅读(22)  评论(0)    收藏  举报