重复的子字符串

给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过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. windows下安装pm2

    安装pm2 npm install pm2 -g 添加系统环境变量 PM2_HOME=C:\Users\PCONE\.pm2 打开新的cmd命令行窗口,执行以下命令来安装服务 pm2-service- ...

  2. java代码关闭tomcat程序

    1.通过java代码实现tomcat的关闭 2.tomcatStop.java package test; import java.io.BufferedReader; import java.io. ...

  3. 【Python图像特征的音乐序列生成】关于小样本的一些思考

    我之前就注意到,深度学习和音乐结合,尤其是从乐理出发进行结合(而不是纯粹的进行音乐生成),是一个尚未被深度挖掘的全新领域.可想而知,这个方向符合我要求的数据肯定是要自己搜集了. 自己搜集的数据,在量上 ...

  4. PHP生成类似类似优酷、腾讯视频等其他视频链的ID

    不知道你注意了没有,类似优酷.腾讯视频等其他视频链接似乎类似这样的 http://v.youku.com/v_show/id_XNjA5MjE5OTM2.html 注意id_xxx那段,是不是看不懂了 ...

  5. idea中pom.xml没有工作 IDEA中maven项目pom.xml依赖不生效解决

    问题: 今天在web项目中需要引入poi相关jar包.查看之下才发现pom.xml中的依赖虽然已经下载到了本地仓库 repository,但是却没有加入到项目路径的 Extenal Libraries ...

  6. 判断是否是同一人的方法——equals()?在Person类中提供一个比较的方法compare()返回boolean值?对象自己和自己比?

    判断是否是同一人的方法——equals() 不能直接用per1==per2,这不是对象内容的比较而是存放对象地址的值得比较 在Person类中提供一个比较的方法compare()返回boolean值 ...

  7. Java中什么是匿名对象,空参构造方法输出创建了几个匿名对象,属性声明成static

    package com.swift; //使用无参构造方法自动生成对象,序号不断自增 public class Person { private static int count; //如果在定义类时 ...

  8. iOS 绘制1像素的线

    一.Point Vs Pixel iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量.系统在实际渲染到设置时会帮助我们处理Point到P ...

  9. 66. Plus One@python

    Given a non-empty array of digits representing a non-negative integer, plus one to the integer. The ...

  10. 如何下载并安装 robomongo 到Ubuntu 系统

    官网下载软件,https://robomongo.org/download wget https://download.robomongo.org/1.2.1/linux/robo3t-1.2.1-l ...