(第15天)【leetcode题解】459、重复的子字符串

目录

  • 459、重复的子字符串
    • 题目描述
    • 暴力匹配
      • 思路
      • 代码
    • 字符串匹配
      • 思路
      • 代码
      • 与暴力匹配的不同
    • KMP解法
      • 思路
      • 代码
      • KMP算法的核心和用途

459、重复的子字符串

题目描述

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

暴力匹配

思路

  1. 推理
  • 如果存在这样的子串,那么这个子串一定是s的前缀
  • s的长度n一定是子串长度n1的整数倍
  • s中的元素s[i]与往前移n1的元素s[i-n1]相同
  1. 方法

因此从小到大枚举出所有可能的子串长度n1,再对这个子串进行上述的判断即可。
优化:这个子串至少要在s中重复一次,所以n1的范围为[1,n/2]。

代码

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        int n = s.size();
        //i代表子串的长度,应从1开始
        for (int i = 1; i <= n / 2; i++) {
            //判断该子串是否为目标子串
            if (n % i == 0) {
                bool match = true;
                //判断之后的字符往前移子串长度i之后是否相等
                //从子串之后开始遍历整个字符串
                for (int j = i; j < n; j++) {
                    if (s[j] != s[j - i]) {
                        match = false;
                        break;
                    } 
                }
                if (match) return true;
            }
        }
        return false;
    }
};

时间复杂度:O(n2);枚举子串的时间复杂度为O(n),遍历判断子串的时间复杂度为O(n)。
空间复杂度:O(1);

字符串匹配

思路

  1. 如果s满足题目要求,那么s具有以下性质:
  • 设s的长度为n,子串长度s1为n1.
  • 可以把s写成n/n1个子串s1排列的形式 : s——>s1s1s1s1…
  • 那么把第一个s1移到最后面,字符串s不变
  1. 根据性质,可以证明:
  • 因为1 <= n1 < n,那么把两个字符串s连在一起得到S
  • 把连在一起后的字符串S移除前后第一个元素
  • 这时,字符串s一定是拼接串S的子串
  1. 根据证明结果,得到方法:
  • 拼接两个字符串s
  • 移除第一个和最后一个字符
  • 如果s是其中的子串,则满足题目要求

代码

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        return (s + s).find(s, 1) != s.size();
    }
};

与暴力匹配的不同

通过推理,得到一种满足要求是的情况,只要针对这个情况进行判断即可。

KMP解法

思路

  1. 假设推理
  • 假设这个文本串由重复子串组成
  • 找到这个文本串的最长公共前后缀
  • 文本串切割掉最长公共前后缀,剩下的就是重复子串
  1. 可用的结论
  • 设文本串s由n个长度为x的子串组成,则文本串全长为nx
  • 最长公共前后缀由m个长度为x的子串组成,长度为mx
  • 则重复子串长度为(n-m)xn-m=1
  • 当全长nx对重复子串长度(n-m)x取余等于0时(即nx % (n-m)x == 0 or nx % x == 0),证明(n-m)x代表的子串为重复子字符串。
  1. 方法
  • 求出next数组,next数组长度为len
  • 使用next数组存储文本串中最长公共前后缀的长度next[len - 1]
  • 如果 len % (len -next[len - 1]) == 0,则表明存在重复子字符串

代码

class Solution {
public:
    //得出next数组
    void getNext(int* next, string& s) {
        //初始化
        int j = 0;//前缀末尾从0开始
        next[0] = j;

        //从长度为2的子串开始求最长公共前后缀长度
        for (int i = 1; i < s.size(); i++) {
            //前后缀末尾不匹配时
            while (j >0 && s[i] != s[j]) j = next[j - 1];//j回退
            //前后缀末尾匹配时
            if (s[i] == s[j]) {
                j++;//j(和i)往后移一位
            }
            next[i] = j;//下标j为当前子串(末尾下标为i)的最长公共前后缀长度
        }
    }

    bool repeatedSubstringPattern(string s) {
        int next[s.size()];//创建长度为字符串长度的前缀表
        getNext(&next[0], s);

        //使用最长公共前后缀长度判断是否由重复的子字符串组成
        int len = s.size();
        //next[len - 1] == 0时,证明整个字符串最长公共前后缀长度为0
        //根据推理得出的结论:当len % (len - next[len-1]) == 0 时证明(有重复的子字符串/最后一段字符串为重复子字符串)
        if (next[len - 1] != 0 && len % (len - next[len-1]) == 0) return true;
        return false;
    }
};

时间复杂度:O(n);得到前缀表时遍历字符串需要O(n),判断重复子字符串只用了固定的操作数。
空间复杂度:O(n);需要前缀表存储字符串的所有前缀子串(包括它自身)的最长公共前后缀长度。

KMP算法的核心和用途

  1. 核心
  • 前缀表next,其中存储了字符串的最长公共前后缀长度
  • 匹配时,使用前缀表记录的最长公共前后缀长度来进行回退
  • 总结:存储字符串的最长公共前后缀长度的前缀表、回退思想。
  1. 用途
  • 使用前缀表回退查找子字符串。
  • 使用前缀表中记录的最长公共前后缀长度来进行一些数字上的判断。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自存angular 自定义snackbar

定义 1.自定义样式 2.自定义组件 就在要使用snackbar的组件中 在module中引入该组件&#xff08;重新写一个组件也行的 直接引入就好&#xff09; 打开这个组件 给这个自定义的组件传参 这个自定义组件接参(类似对话框接参) 使用参数 在这个自定义组件中 做了点击如何关闭s…

企业信使运营管理平台功能介绍

企业信使运营管理平台是一种为企业提供内部协同、任务管理、沟通交流、文件共享等功能的综合性管理平台。该平台旨在提高企业内部的工作效率和沟通协作能力&#xff0c;提供便捷的工作管理工具&#xff0c;促进企业的业务发展。 内部协同功能 企业信使运营管理平台首先提供一种…

Navicat Data Modeler Ess for Mac:强大的数据库建模设计软件

Navicat Data Modeler Ess for Mac是一款专为Mac用户设计的数据库建模与设计工具&#xff0c;凭借其强大的功能和直观的界面&#xff0c;帮助用户轻松构建和管理复杂的数据库模型。 Navicat Data Modeler Ess for Mac v3.3.17中文直装版下载 这款软件支持多种数据库系统&#x…

android进阶-AIDL

参考&#xff1a;Android进阶——AIDL详解_android aidl-CSDN博客 AIDL&#xff08;Android 接口定义语言&#xff09;&#xff0c;可以使用它定义客户端与服务端进程间通信&#xff08;IPC&#xff09;的编程接口&#xff0c;在 Android 中&#xff0c;进程之间无法共享内存&…

全视通助力珠海市井岸镇卫生院新院,建设智慧病房

5月6日&#xff0c;位于珠海市斗门区的井岸镇卫生院新院正式启用&#xff0c;面向市民开诊。新院各诊区就医秩序井然&#xff0c;总体情况良好。据统计&#xff0c;截至开诊当天11点30分&#xff0c;新院门诊共接诊347人次&#xff0c;预防接种81人次&#xff0c;儿童体检33人次…

Docker快速搭建NAS服务——NextCloud

Docker快速搭建NAS服务——NextCloud 文章目录 前言NextCloud的搭建docker-compose文件编写运行及访问 总结 前言 本文主要讲解如何使用docker在本地快速搭建NAS服务&#xff0c;这里主要写如下两种&#xff1a; FileBrowser1&#xff1a;是一个开源的Web文件管理器&#xff…

effective python学习笔记_类与接口

用组合类实现多层结构而不用内置类型 例子&#xff1a;成绩单&#xff0c;存储学生各科成绩多个然后加权重&#xff0c;如果用字典类型会导致字典有多层嵌套结构 思想 当用内置类型如字典元组等结构出现超过二层的多层嵌套结构时&#xff0c;读起来会比较难懂&#xff0c;此时…

新能源 锂电池行业创业的财富方案,锂电池回收实战攻略课(36节课)

实战攻略 12年锂电池回收行业经验与坑全收录 课程内容&#xff1a; 001-课程介绍.mp4 002-锂电池的全种类认识.mp4 003-废品锂电池到级片粉末价值估算,mp4 004-锂电池的生产应用回收,mp4 005-梯次回收到粉未提纯全流程,mp4 006-锂电池行业术语,mp4 007-回收所需必备工具…

汉诺塔问题和爬楼梯(递归)

感谢大佬的光临各位&#xff0c;希望和大家一起进步&#xff0c;望得到你的三连&#xff0c;互三支持&#xff0c;一起进步 个人主页&#xff1a;LaNzikinh-CSDN博客 c语言基础_LaNzikinh篮子的博客-CSDN博客 文章目录 一.爬楼梯问题二.汉诺塔问题总结 一.爬楼梯问题 假设你正…

Ansys界面设计:ACT入门

来自官方文档Getting Started with ACT&#xff0c;机翻。 Ansys 提供一流的现成仿真技术。为了最有效地部署普遍模拟&#xff0c;您可能需要更精心策划的体验&#xff0c;以使我们的模拟专业知识与您的用户、公司或行业需求相匹配。 Ansys ACT 使您能够自定义和扩展 Ansys 体验…

java注解全网最细

引言 在java编程中&#xff0c;注解&#xff08;Annotation&#xff09;是一种元数据&#xff0c;它提供了关于程序代码的额外信息。注解不直接影响程序的执行&#xff0c;但可以在运行时提供有关程序的信息&#xff0c;或者让编译器执行额外的检查。 下面笔者通过循序渐进的…

快速上手文心一言指令

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

PHP基础教程

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;PHP &#x1f4da;参考教程&#xff1a;菜鸟\编程网❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、PHP语法 基本的 PHP 语法 PHP 注释 PHP空白不敏…

Kafka分级存储概念(一)

Kafka分级存储及实现原理 概述 Kafka社区在3.6版本引入了一个十分重要的特性: 分级存储,本系列文章主要旨在介绍Kafka分级存储的设计理念、设计细节以及具体的代码实现 背景:为什么要有分级存储? 场景 作为一款具有高吞吐及高性能的消息中间件,Kafka被广泛应用在大数据、…

Linux添加IP地址的方法

1.nmcli&#xff1a;命令式的添加IP地址 [rootlocalhost ~]#nmcli connection modify eno16777736 ipv4.addresses 192.168.126.100/24 ipv4.gateway 192.168.126.1 ipv4.method manual connection.autoconnect yes [rootlocalhost ~]# nmcli connection modify eno16777736 i…

Spring Cloud Alibaba Sentinel 集成与限流实战(6)

项目的源码地址 Spring Cloud Alibaba 工程搭建&#xff08;1&#xff09; Spring Cloud Alibaba 工程搭建连接数据库&#xff08;2&#xff09; Spring Cloud Alibaba 集成 nacos 以及整合 Ribbon 与 Feign 实现负载调用&#xff08;3&#xff09; Spring Cloud Alibaba Ribbo…

RFID在汽车制造中的应用如何改变行业

随着工业4.0和中国制造2025的推进&#xff0c;企业对于智能化、自动化的需求日益增长&#xff0c;RFID射频技术在制造业中已经相当普遍了。在如今这瞬息万变的行业与时代中&#xff0c;RFID技术可以帮助企业获得竞争优势&#xff0c;简化日益复杂的生产流程&#xff0c;推动企业…

*args和**kwargs的使用

*args传入的是按照顺序的不定长度的参数列表 **kwargs传入的是不定长度的键值对

AI 资料汇总专栏

包含AI资料、大模型资料、AI最新行业发展 人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;是一门研究如何使计算机能够具备智能行为的科学与技术。它致力于开发出能够像人类一样思考、学习、理解和决策的计算机系统。自20世纪50年代以来&#xff…

《第一行代码》第二版学习笔记(11)——最佳的UI体验

文章目录 一、Toolbar二、滑动菜单1、DrawerLayout——抽屉2、NavigationView 三、悬浮按钮和可交互提示1、FloatingActionButton——悬浮按钮2、Snackbar——提示工具3、CoordinatorLayout 四、卡片式布局1、cardView2、AppBarLayout 五、下拉刷新——SwipeRefreshLayout六、可…