459. 重复的子字符串

news2024/12/23 12:20:10

459. 重复的子字符串

  • 原题链接:
  • 完成情况:
  • 解题思路:
  • 参考代码:
    • __459重复的子字符串_枚举
    • __459重复的子字符串_字符串匹配
    • __459重复的子字符串_KMP算法
    • __459重复的子字符串_优化的KMP算法
  • 错误经验吸取

原题链接:

459. 重复的子字符串

https://leetcode.cn/problems/repeated-substring-pattern/submissions/

完成情况:

在这里插入图片描述

解题思路:

思路与算法

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

nnn 一定是 n′n'n 
′
  的倍数;

s′s's 
′
  一定是 sss 的前缀;

对于任意的 i∈[n′,n)i \in [n', n)i∈[n 
′
 ,n),有 s[i]=s[i−n′]s[i] = s[i-n']s[i]=s[i−n 
′
 ]。

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

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

参考代码:

__459重复的子字符串_枚举

package 代码随想录.字符串;

public class __459重复的子字符串_枚举 {
    //给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
    /**
    方法一: 双重for循环,其中一个for循环,用i,j记录起始,截止位置;;另一个for循环,用于剩余的j到结尾。
     */
    public boolean repeatedSubstringPattern(String s) {
        /*
        提示:
            1 <= s.length <= 104
            s 由小写英文字母组成
        解法1:调用KMP算法/暴力for循环?,将一个部分,分成从[0,i]和[i+1,s.length-1]的两个子串。
         */
        int n = s.length();
        for (int i = 1;i*2 <= n;i++){   //要能够匹配,最多只能遍历一般即可。
            if (n % i == 0){    //把i作为匹配对象
                boolean match = true;
                for (int j = i;j < n;j++){     //j是匹配位置
                    if (s.charAt(j)!= s.charAt(j-i)){   //同步j-i位置。【i为配对对象】
                        match = false;
                        break;
                    }
                }
                if (match){
                    return true;
                }
            }
        }
        return false;
    }
}

__459重复的子字符串_字符串匹配

package 代码随想录.字符串;

public class __459重复的子字符串_字符串匹配 {
    /**
     * 调用方法进行配对
     *
     * @param s
     * @return
     */
    public boolean repeatedSubstringPattern(String s){
       return (s+s).indexOf(s,1) != s.length();
    }
}

__459重复的子字符串_KMP算法

package 代码随想录.字符串;

import java.util.Arrays;

public class __459重复的子字符串_KMP算法 {
    public boolean repeatedSubstringPattern(String s) {
        //确定一个固定的长度的字符串,去kmp配对另一个相同长度的字符串。
        return myKMP(s+s,s);    //这道题的原本是判别s是否是由某组字符重复构成
    }

    /**
     *
     * @param query
     * @param pattern
     * @return
     */
    private boolean myKMP(String query, String pattern) {
        int n = query.length();
        int m = pattern.length();
        int  [] fail = new int[m];
        Arrays.fill(fail,-1);
        for (int i = 1;i<m;i++){
            int j = fail[i-1];
            while (j != -1 && pattern.charAt(j+1)!= pattern.charAt(i)){
                j = fail[j];
            }
            if (pattern.charAt(j+1) == pattern.charAt(i)){
                fail[i] = j +1;
            }
        }
        int match = -1;
        for (int i = 1;i<n-1;i++){
            while (match != -1 && pattern.charAt(match + 1) != query.charAt(i)){
                match = fail[match];
            }
            if (pattern.charAt(match + 1) == query.charAt(i)){
                match++;
                if (match == m-1){
                    return true;
                }
            }
        }
        return false;
    }
}

__459重复的子字符串_优化的KMP算法

package 代码随想录.字符串;

import java.util.Arrays;

public class __459重复的子字符串_优化的KMP算法 {
    public boolean repeatedSubstringPattern(String s) {
        //确定一个固定的长度的字符串,去kmp配对另一个相同长度的字符串。
        return myKMP(s);    //这道题的原本是判别s是否是由某组字符重复构成
    }

    /**
     *
     * @param pattern
     * @return
     */
    private boolean myKMP(String pattern) {
       int n = pattern.length();
       int [] fail = new int[n];
       Arrays.fill(fail,-1);
       for (int i = 1;i<n;i++) {
           int j = fail[i-1];
           while (j!= -1 && pattern.charAt(j+1)!= pattern.charAt(i)){
               j = fail[j];
           }
           if (pattern.charAt(j+1) == pattern.charAt(i)){
               fail[i] = j +1;
           }
       }
       return fail[n-1] != -1 && n%(n- fail[n-1] - 1) == 0 ;
    }

}

错误经验吸取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1199865.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C 用户定义函数

C 用户定义函数 在本教程中&#xff0c;您将借助示例学习在C语言编程中创建用户定义的函数。 函数是执行特定任务的代码块。 C允许您根据需要定义函数。这些函数称为用户定义函数。例如&#xff1a; 假设您需要创建一个圆并根据半径和颜色为其着色。您可以创建两个函数来解…

No182.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

C语言数据结构-----双向链表增删查改的代码实现

文章目录 1.初始化双链表2.创建链表节点3.打印链表4.尾插5.尾删6.头插7.头删8.在pos之前插入8.1 在pos之前插入(改造头插)8.2 在pos之前插入(改造尾插) 9.删除pos位置9.1 删除pos位置(改造尾删)9.1 删除pos位置(改造头删) 10.查找11.毁灭 链接: 顺序表(动态顺序表增删查改的代码…

基于SSM的微博网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Python基础入门例程54-NP54 被5整除的数字(循环语句)

最近的博文&#xff1a; Python基础入门例程53-NP53 前10个偶数(循环语句)-CSDN博客 Python基础入门例程52-NP52 累加数与平均值(循环语句)-CSDN博客 Python基础入门例程51-NP51 列表的最大与最小(循环语句)-CSDN博客 目录 最近的博文&#xff1a; 描述 输入描述&#xf…

Redis 5大数据类型命令解读

目录 Redis key的命令 Redis 10大数据类型 1、redis字符串&#xff08;String&#xff09; 2、redis列表(List) 3、redis哈希表(Hash) 4、redis集合(Set) 5、redis有序集合(ZSet) Redis 命令网站&#xff1a;redis中文文档 Redis key的命令 命令说明示例keys *查看当…

人工智能基础——图像认知与OpenCV

人工智能的学习之路非常漫长&#xff0c;不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心&#xff0c;我为大家整理了一份600多G的学习资源&#xff0c;基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

【Python基础】try-finally语句和with语句

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

灰度与二值化

人工智能的学习之路非常漫长&#xff0c;不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心&#xff0c;我为大家整理了一份600多G的学习资源&#xff0c;基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

No180.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

统计学_蒙特卡罗方法

1、蒙特卡罗方法的基本思想 蒙特卡罗方法(Monte Carlo method)是由冯诺依曼和乌拉姆等人发明的&#xff0c;“蒙特卡罗”这个名字是出自摩纳哥的蒙特卡罗赌场&#xff0c;这个方法是一类基于概率的方法的统称&#xff0c;不是特指一种方法。 蒙特卡罗方法也成统计模拟方法&am…

【彻底搞懂C指针 】Malloc 和 Free 的具体实现 (笔记)

【彻底搞懂C指针】Malloc 和 Free 的具体实现 https://danluu.com/malloc-tutorial/ 进程间的通信 : ①共享内存 ② 消息传递 &#xff08;内核实现&#xff09; 分配策略 (实现方面) by DUCK sbrk() malocal实现的主要函数 man sbrk 查看 数据结构 一个参考代码 https…

软件架构的可维护性指标——代码圈复杂度

代码圈复杂度 1、目的2、前言3、简介4、案例5、降低6、插件7、总结 1、目的 区别于常规的高内聚、低耦合、抽象、封装这种定性的指标&#xff0c;我想通过对软件架构可维护性的可量化的指标的分享&#xff0c;帮助大家在日常的开发工作中&#xff0c;有一个更为广阔的视角去审…

No181.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

共享内存原理和实现

实现原理 实现函数 1&#xff0c;ftok--shmget--shmat--shmdt shmget用于分配映射物理内存的虚拟内存。 怎么保证不同进程访问同一块物理内存呢 key_t ftok(const char *pathname, int proj_id); ftok的第一个参数是一个文件&#xff0c;只要使用同一个文件进行映射&#x…

STM32F4之看门狗

1、 看门狗作用 单片机复位的方式&#xff1a;硬件复位 -- reset按键 上电复位 -- 电容 看门狗复位 看门狗的复位功能主要是用于一些平常难以操作的场合去帮助我们进行复位操作。当你单片机突然死机或者程序跑飞了&#xff0c;看门狗就可以检测得到并且及时帮你复位。看门狗也可…

74hc595模块参考

74hc595模块参考 8位串行并行输出&#xff08;SIPO&#xff09;移位寄存器 使用74HC595移位寄存器扩展微控制器上的输出引脚数量。如果你需要扩充输入引脚的数量那么你需要74HC165移位寄存器。 SER&#xff08;串行输入&#xff09;引脚用于一次一位地将数据发送到移位寄存器…

(离散数学)逻辑连接词

异或可以理解为不同为1相同为0 P->Q的前件和后件满足0->1的其中一个就为真 <—>可以看做 &#xff0c;相同为1不同为0 异或与等价相反

Torch Hub 系列#2:VGG 和 ResNet

一、说明 在上一篇教程中,我们了解了 Torch Hub 背后的本质及其概念。然后,我们使用 Torch Hub 的复杂性发布了我们的模型,并通过相同的方式访问它。但是,当我们的工作要求我们利用 Torch Hub 上提供的众多全能模型之一时,会发生什么? 在本教程中,我们将学习如何利用称为…

MySQL:日志系统

目录 概述错误日志&#xff08;error log&#xff09;慢查询日志&#xff08;slow query log&#xff09;一般查询日志( general log )中继日志&#xff08;relay log&#xff09;Buffer Pool 缓存回滚日志&#xff08;undo log)概述undo log 作用undo log 的存储机制Undo log …