首页 > 其他分享 >LeetCode459.重复的子字符串

LeetCode459.重复的子字符串

时间:2023-10-29 22:56:16浏览次数:32  
标签:后缀 重复 LeetCode459 next int length 拼接 字符串

题目描述

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

示例

image

提交的代码

十五分钟内没想出来怎么解决,没代码:(

学习到的东西

因为个人没有想出来怎么解决,看的是Carl大神的解法,地址我放在下面:
移动匹配以及KMP解此题
然后我写一下我个人理解的地方吧,记录下个人笔记。

移动匹配

如果整体字符串是由若干子字符串重复组成的话,那么这个字符串的第一个子字符串和最后一个子字符串一定是相等的。
image
所以这个字符串两倍拼接在一起的时候,一定可以从拼接的字符串中再次找到这个字符串(除了拼接在一起的第一个和第二个字符串)。下图中橙色框代表可以在新拼接的字符串中搜索的范围(要避开0索引和最后一个索引,毕竟是新拼接在一起的),红色框则代表从拼接中寻找出原字符串的其中一个。
image
所以代码思想也很简单,避开新拼接的字符串的0索引和最后一个索引去寻找原来的字符串是否存在于当前新的字符串中,我这里用的Java中的contains方法。

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        String temp=s;
        s += s;
        s = s.substring(1, s.length()-1);
        return s.contains(temp);
    }
}

KMP算法

KMP算法中的next数组索引位的值就代表当前相等的前后缀的长度,而当前题目的特性是字符串是由子字符串重复构成,那么最长的前后缀一定也是由子字符串构成的,所以最长前后缀的差集一定是子字符串,证明如下。其中绿色代表最长前缀,橙色代表最长后缀,下一张图的红色代表差集。
image
image
图中的最长前缀和最长后缀简称为p,s数组,原数组为f。
因为最长前后缀是相等的,所以 p[0]=s[0],p[1]=s[1],p[2]=s[2],而s[0]=f[3],s[1]=f[4],s[2]=f[5];p[0]=f[0],p[1]=f[1],p[2]=f[2],
所以可以证得f[0]=f[3],f[1]=f[4],f[2]=f[5],重复循环下去就可以证得字符串是由子字符串重复构成。
所以KMP算法来解决这道题的关键在于:如果字符串长度为len,next[len-1]为当前字符串最长的前后缀长度,且如果当前字符串真的是由子字符串重复构成,那么len%(len-next[len-1])==0。
代码如下:

class Solution {
    //KMP算法实现查找重复子字符串
    public boolean repeatedSubstringPattern(String s) {
        int[] next=new int[s.length()];
        //获取next数组
        getNext(next,s);
        int maxLength=next[s.length()-1];
        return maxLength>0&&s.length() % (s.length() - maxLength) == 0;
    }

    public void getNext(int[] next,String needle){
        //赋初始值
        int j=0;
        
        for(int i=1;i<needle.length();i++){
            //若前后缀判断不等,则j向前移动
            while(j>0&&needle.charAt(i)!=needle.charAt(j))j=next[j-1];

            if(needle.charAt(i)==needle.charAt(j))j++;
            
            //j也等于相同前后缀的长度
            next[i]=j;
        }
    }
}

标签:后缀,重复,LeetCode459,next,int,length,拼接,字符串
From: https://www.cnblogs.com/whitePuPigeon/p/17796739.html

相关文章

  • C++小练习:字符串分割的高性能实现
    字符串分割是日常工作中比较常见的基础函数,通常大家会使用现成的基础库,基础库的性能是否是最佳的?本文基于一个周末小练习,研究如何最大限度的提升字符串分割的性能。  1、背景字符串按照分隔符拆成多个子串在日常工作中很常见,譬如:后台服务对配置的解析、模型服务对输入特征的......
  • 字符串、线性表、队列、栈、哈希表、dfs、bfs
    题目列表:1.字符串无重复字符的最长子串(中等难度)给定一个字符串s,请你找出其中不含有重复字符的最长子串的长度。AC代码,展开查看classSolution{public:intlengthOfLongestSubstring(strings){intres=0;unordered_map<char,int>heap......
  • SQL Server数据库连接字符串的几种写法整理
     SQLServer数据库连接字符串的几种写法整理一、远程连接SQLServer数据库1.sqlserver身份验证连接字符串:privatestringConnstrSqlServer="server=数据库地址及实例;uid=数据库账号;pwd=数据库密码;database=数据库名";2.windows身份验证连接字符串:privatestr......
  • 对于字符串,例如d(d)jjhd{f},判断括号是否符合规范
    publicbooleanisValid(Strings){Stack<Character>stack=newStack<>();Map<Character,Character>map=newHashMap<>();char[]chars=s.toCharArray();map.put(')','(');......
  • 一个字符串 AbAbcBaB 这种 消除驼峰字段 AbA aBa 这种 只留下非驼峰比如刚才这个字符
    publicclassSolution{char[]c=s.toCharArray();intlen=c.length;if(len<=2){System.out.println(c[len]);}intj=-1;for(inti=0;i<len-2;i++){if(c[i]==c[i+2]&&c[i]!=c[i+1]){j=i+2;......
  • 字符串的总引力
    字符串的引力定义为:字符串中不同字符的数量。例如,"abbca"的引力为3,因为其中有3个不同字符'a'、'b'和'c'。给你一个字符串s,返回其所有子字符串的总引力。子字符串定义为:字符串中的一个连续字符序列。1.区间贡献法从左往右遍历,优先计算左边同一字符做出的贡......
  • 【题解】P9753 [CSP-S 2023] 消消乐(字符串哈希,DP)
    【题解】P9753[CSP-S2023]消消乐不知道考场脑子是抽了还是有病,全程都不知道在放什么屁。特别鸣谢:@dbxxx给我讲解了解法一的满分做法,并让我对哈希有了更加深刻的认识;@Daidly给我讲解了解法二。题目链接P9753[CSP-S2023]消消乐题意概述给定一个长度为\(n\)的只含小......
  • 无重复字符的最长子串(给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长
    importjava.util.*;publicclassSolution{/***代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可***@paramarrint整型一维数组thearray*@returnint整型*/publicintmaxLength(int[]arr){......
  • 28. 找出字符串中第一个匹配项的下标
    目录题目法一、KMP法二、切片法三、两行题目给你两个字符串 haystack和needle,请你在haystack字符串中找出needle字符串的第一个匹配项的下标(下标从0开始)。如果 needle不是haystack的一部分,则返回 -1。示例1:输入:haystack="sadbutsad",needle="sad"......
  • 如何遍历字符串的单词?
    内容来自DOChttps://q.houxu6.top/?s=如何遍历字符串的单词?如何遍历由空格分隔的单词组成的字符串中的单词?请注意,我对C字符串函数或那种字符操作/访问不感兴趣。我更喜欢优雅而不是效率。我目前的解决方法:#include<iostream>#include<sstream>#include<string>using......