重复的子字符串

给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。

示例 1:

输入: "abab"

输出: True

解释: 可由子字符串 "ab" 重复两次构成。

示例 2:

输入: "aba"

输出: False

示例 3:

输入: "abcabcabcabc"

输出: True

解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)

复习一下KMP算法

KMP的主要思想是利用字符串自身的前缀后缀的对称性,来构建next数组,从而实现用接近O(N)的时间复杂度完成字符串的匹配

对于一个字符串str,next[j] = k 表示满足str[0...k-1] = str[j-k...j-1]的最大的k,即对于子串str[0...j-1],前k个字母等于后k个字母

现在求解str的next数组:

初始化:next[0] = -1

那么在知道了next[j]的情况下,如何递推地求出next[j+1]呢?分两种情况(令k=next[j]):

  1、如果str[j]==str[k],则next[j+1] = k+1

  如下图所示,对于str[0...j-1],前k个字母等于后k个字母(两个绿色部分相等),然后str[k]刚好是前k个字母的下一个字母(第一个红色)

  如果str[j]==str[k],说明对于str[0...j],前k+1个字母等于后k+1个字母(绿色+红色=绿色+红色),即等于next[j]+1(绿色长度为k,红色长度为1)

  2、如果str[j]!=str[k],则k=next[k],然后继续循环(回到1),直到k=-1

  因为str[j]!=str[k](下图中紫色和红色不相等),所以前k+1个字母不再等于后k+1个字母了

  但是由于前k个字母还是等于后k个字母(图中两个黑色虚线框住部分),所以对于任意的k'<k,str[k-k'...k-1]=str[j-k'...j-1](图中第二个和最后一个绿色相等)

  而next[k]表示str[0...k-1]内部的对称情况,所以令k'=next[k],则对于str[0...k-1],前k'个字母等于后k'个字母(图中第一个和第二个绿色相等)

  由于图中第二个绿色始终=第四个绿色,所以第一个绿色等于第四个绿色

  因此将k=next[l]继续带入循环,回到判断1:

    如果str[k']=str[j],则满足前k'+1个字母等于后k'+1个字母(两个浅黄色区域相等),所以next[j+1] = k'+1;

    否则,继续k'=next[k']继续循环,直到k'=-1说明已经到达第一个元素,不能继续划分,next[j+1]=0

得到了求next数组的递推方法后,现在用C++实现

 void getNext(string str,int next[]){
int len=str.length();
next[0]=-1;
int j=0,k=-1;
while(j<len-1){
if(k==-1||str[j]==str[k])
next[++j]=++k;
else
k=next[k];
}
}

这里解释一下:由于每一轮赋值完next[j]后,k要不然是-1,要不然是next[j](上次匹配的前缀的下一个位置)

如果k=-1,说明next[j+1]=0=k+1;否则如果str[j]==str[k],说明前k+1个字母等于后k+1个字母,直接next[j+1]=k+1

所以循环中if后的语句为"next[++j] = ++k;"

思路

假设str长度为len,重复的子串长度为k,则如果真的由连续多个长度为k的子串重复构成str,那么在对str求next时,由于连续对称性(如图,前后两个虚线框内字符串相等),会从next[k+1]开始,1,2,3...地递增,直到next[len]=len-k,且(len-k)%k==0,表示有整数个k

要一直求到next[len]而不是next[len-1],是因为next[len-1]只是表示前len-1个字母的内部对称性,而没有考虑到最后一个字母即str[len-1]

所以求解很简单:先对str求next数组,一直求到next[len],然后看看next[len]是否非零且整除k(k=len-next[len])

 class Solution {
public boolean repeatedSubstringPattern(String s) {
int len=s.length();
int[] next=new int[len+1];
next[0]=-1;
int j=0,k=-1;
while(j<len){
if(k==-1||s.charAt(j)==s.charAt(k)){
next[++j]=++k;
}else{
k=next[k];
}
}
return (next[len]>0)&&next[len]%(len-next[len])==0;
}
}

Leetcode 459.重复的子字符串的更多相关文章

  1. LeetCode 459. 重复的子字符串(Repeated Substring Pattern)

    459. 重复的子字符串 459. Repeated Substring Pattern 题目描述 给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成.给定的字符串只含有小写英文字母,并且 ...

  2. Java实现 LeetCode 459 重复的子字符串

    459. 重复的子字符串 给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成.给定的字符串只含有小写英文字母,并且长度不超过10000. 示例 1: 输入: "abab" ...

  3. 459 Repeated Substring Pattern 重复的子字符串

    给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成.给定的字符串只含有小写英文字母,并且长度不超过10000.示例 1:输入: "abab"输出: True解释: 可由 ...

  4. 【leetcode 简单】 第一百一十二题 重复的子字符串

    给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成.给定的字符串只含有小写英文字母,并且长度不超过10000. 示例 1: 输入: "abab" 输出: True 解释 ...

  5. [Swift]LeetCode459. 重复的子字符串 | Repeated Substring Pattern

    Given a non-empty string check if it can be constructed by taking a substring of it and appending mu ...

  6. python面试题一个字符串是否由重复的子字符串组成

    一,给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成.给定的字符串只含有小写英文字母,并且长度不超过10000. 输入: "abab" 输出: True 解释: 可由 ...

  7. Leetcode459.Repeated Substring Pattern重复的子字符串

    给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成.给定的字符串只含有小写英文字母,并且长度不超过10000. 示例 1: 输入: "abab" 输出: True 解释 ...

  8. LeetCode 686. 重复叠加字符串匹配(Repeated String Match)

    686. 重复叠加字符串匹配 686. Repeated String Match 题目描述 给定两个字符串 A 和 B,寻找重复叠加字符串 A 的最小次数,使得字符串 B 成为叠加后的字符串 A 的 ...

  9. [LeetCode] Repeated Substring Pattern 重复子字符串模式

    Given a non-empty string check if it can be constructed by taking a substring of it and appending mu ...

随机推荐

  1. EasyUI Tabs + Yii2.0实现iframe方式打开页面(解决共用静态文件引入加载的问题)

    在项目实际开发中,有将打开的各个链接页面隔离的需求(防止静态资源起冲突),这个时候常规思路就是使用iframe来实现!但遇到一个比较棘手的问题,当用easyui Tabs打开一个iframe页面时,怎 ...

  2. 【LeetCode】9 Palindrome Number 回文数判定

    题目: Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could neg ...

  3. [会员登入] 透过 E-Mail进行身份认证、启用会员权利

    [會員登入] 透過 E-Mail進行身份認證.啟用會員權利 这个问题是在论坛上看见的 其实,遇见问题的时候,我会建议初学者先想一下「流程」 您想怎么作?需要哪些步骤? 一旦「流程」清楚了 您是哪一步骤 ...

  4. codeforce Gym 100342H Hard Test (思考题)

    题意:构造让Dijkstra单源最短路算法有效松弛次数最多的数据... 题解:构造,题意换种说法就是更新晚的路径要比更新早的路径短.因为所有点都会更新一次,那么按照更新时间形成一条链,即到最后一个点的 ...

  5. UVA11212 EditingaBook ( IDA*搜索)

    首先说说IDS,就DFS限定一个层数上限maxd,如果在maxd范围内没有找到解,就增加maxd,继续搜索. 当访问到当前结点u时,估计还要搜索h(u)层,如果h(u)+当前层数d>maxd的时 ...

  6. Google 出品的 Java 编码规范,强烈推荐,权威又科学!

    原文:google.github.io/styleguide/javaguide.html 译者:Hawstein 来源:hawstein.com/2014/01/20/google-java-sty ...

  7. helm install

    reference 前提:已安装k8s:v1.10.4 helm install on master(无需下载官方tar包) 链接:https://pan.baidu.com/s/1Ji3Ru1pTQ ...

  8. HTML5<figure>元素

    HTML5<figure>元素是用来定义页面文档中独立的流内容(图像,图表,照片,代码块),figure内容与主内容有关,如果被删除,则不影响主文档流的产生. HTML5<figca ...

  9. 【转】MFC消息映射详解(整理转载)

    消息:主要指由用户操作而向应用程序发出的信息,也包括操作系统内部产生的消息.例如,单击鼠标左按钮,windows将产WM_LBUTTONDOWN消息,而释放鼠标左按钮将产生WM_LBUTTONUP消息 ...

  10. pandas中的随机排序和抽样

    1.随机重排序 使用take()随机排序 如: df.take([54])   #采取索引为54的数据 可以借助np.random.permutation()函数随机排序 permutation()函 ...