代码随想录训练营day09|459.重复的子字符串


前言

代码随想录算法训练营day09


一、459.重复的子字符串

1.题目

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

示例 1:

输入: s = "abab" 输出: true 解释: 可由子串 "ab" 重复两次构成。

示例 2:

输入: s = "aba" 输出: false

示例 3:

输入: s = "abcabcabcabc" 输出: true 解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)

提示:

复制代码

matlab

复制代码

1 <= s.length <= 104 s 由小写英文字母组成

来源:力扣(LeetCode) 链接:leetcode.cn/problems/re...

2.解题思路

  1. 方法一:枚举

如果一个长度为 nn 的字符串 ss 可以由它的一个长度为 n′n′ 的子串 s′s′ 重复多次构成,那么:

复制代码

css

复制代码

nn 一定是 n′n′ 的倍数; s′s′ 一定是 ss 的前缀; 对于任意的 i∈[n′,n)i∈[n′,n),有 s[i]=s[i−n′]s[i]=s[i−n′]。

也就是说,ss 中长度为 n′n′ 的前缀就是 s′s′,并且在这之后的每一个位置上的字符 s[i]s[i],都需要与它之前的第 n′n′ 个字符 s[i−n′]s[i−n′] 相同。

因此,我们可以从小到大枚举 n′n′,并对字符串 ss 进行遍历,进行上述的判断。注意到一个小优化是,因为子串至少需要重复一次,所以 n′n′ 不会大于 nn 的一半,我们只需要在 [1,n2][1,2n​] 的范围内枚举 n′n′ 即可。

  1. 方法二:字符串匹配

我们可以把字符串 ss 写成

复制代码

复制代码

s′s′⋯s′s′s′s′⋯s′s′

的形式,总计 nn′n′n​ 个 s′s′。但我们如何在不枚举 n′n′ 的情况下,判断 ss 是否能写成上述的形式呢?

如果我们移除字符串 ss 的前 n′n′ 个字符(即一个完整的 s′s′),再将这些字符保持顺序添加到剩余字符串的末尾,那么得到的字符串仍然是 ss。由于 1≤n′<n1≤n′<n,那么如果将两个 ss 连在一起,并移除第一个和最后一个字符,那么得到的字符串一定包含 ss,即 ss 是它的一个子串。

因此我们可以考虑这种方法:我们将两个 ss 连在一起,并移除第一个和最后一个字符。如果 ss 是该字符串的子串,那么 ss 就满足题目要求。

注意到我们证明的是如果 ss 满足题目要求,那么 ss 有这样的性质,而我们使用的方法却是如果 ss 有这样的性质,那么 ss 满足题目要求。因此,只证明了充分性是远远不够的,我们还需要证明必要性。

证明需要使用一些同余运算的小技巧,可以见方法三之后的「正确性证明」部分。这里先假设我们已经完成了证明,这样就可以使用非常简短的代码完成本题。在下面的代码中,我们可以从位置 11 开始查询,并希望查询结果不为位置 nn,这与移除字符串的第一个和最后一个字符是等价的。

3.代码实现

方法一:枚举

复制代码

java

复制代码

class Solution { public boolean repeatedSubstringPattern(String s) { int n = s.length(); for (int i = 1; i * 2 <= n; ++i) { if (n % i == 0) { boolean match = true; for (int j = i; j < n; ++j) { if (s.charAt(j) != s.charAt(j - i)) { match = false; break; } } if (match) { return true; } } } return false; } }

方法二:字符串匹配

复制代码

java

复制代码

class Solution { public boolean repeatedSubstringPattern(String s) { return (s + s).indexOf(s, 1) != s.length(); } }

相关推荐
咕咕吖28 分钟前
对称二叉树(力扣101)
算法·leetcode·职场和发展
九圣残炎1 小时前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
lulu_gh_yu1 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
丫头,冲鸭!!!1 小时前
B树(B-Tree)和B+树(B+ Tree)
笔记·算法
Re.不晚1 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
为什么这亚子2 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
3 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
~yY…s<#>3 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
幸运超级加倍~4 小时前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
yannan201903134 小时前
【算法】(Python)动态规划
python·算法·动态规划