重复子字符串
问题描述:判断一个字符串是否由一个子字符串重复多次构成
比如”abab”就是一个由子字符串”ab”重复构成的,下面介绍一下这个问题的几种解决思路:
1. 暴力解
假设字符串s
的长度为n
,那我们就穷举s
所有可能字串s_sub
,值得注意的是字串s_sub
的长度m
一定是n
的因子且小于n/2
,然后我们就可以开始穷举字串了~
复杂度分析:
- 时间复杂度:$O(n^2)$, 穷举所有长度时间复杂度为$O(n)$, 遍历
s
字符串时间复杂度为$O(n)$ - 空间复杂度:$O(1)$
2. 双倍字符串
这是我感觉最神奇的解法,而且高效!
我们首先将两个s
拼接在一起得到一个新的字符串,然后去掉首尾的两个字符,再判断s
是否为该新串的字串即可!
怎么理解?我们不妨假设s
是一个由重复字串构成的串(如下图), 去掉首位字符后s
仍然会是新串的字串!
但是值得注意的是,我们只是说明了必要条件(s
是是由重复字串构成 → s
会具有上述性质),但是我们使用该算法时需要用到的是充分条件(s
具有上述性质 → s
是是由重复字串构成)
事实上充分条件是满足的,可以使用数学严谨的推导,可以参考leetcode官方解答
使用上述性质,我们就能轻松秒杀这道题了
1 |
|
3. KMP算法
直接去阅读代码,是永远无法学会KMP算法的,读者甚至无法理解KMP算法关键代码中的任意一行
KMP算法有着良好的理论时间复杂度上限,但是大多数语言自带的字符串查找函数并不是用KMP算法,而是使用普通暴力匹配算法盒优化的BM算法,因为这些算法具有更优秀的平均时间复杂度。
我感觉这篇KMP算法讲的很通俗易懂,赞!