当前位置: 首页 > news >正文

刷题DAY9 | LeetCode 28-实现 strStr() 459-重复的子字符串

28-实现 strStr()(easy)

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。

思路:kmp算法实现,关键是构建next数组

代码实现:

class Solution {
public:void getNext(int* next, const string& s) {int j = 0;next[0] = 0;for(int i = 1; i < s.size(); i++) {while (j > 0 && s[i] != s[j]) {j = next[j - 1];}if (s[i] == s[j]) {j++;}next[i] = j;}}int strStr(string haystack, string needle) {if (needle.size() == 0) {return 0;}int next[needle.size()];getNext(next, needle);int j = 0;for (int i = 0; i < haystack.size(); i++) {while(j > 0 && haystack[i] != needle[j]) {j = next[j - 1];}if (haystack[i] == needle[j]) {j++;}if (j == needle.size() ) {return (i - needle.size() + 1);}}return -1;}
};
  • 时间复杂度:O(n+m)
  • 空间复杂度:O(m)

详细解释:
思路视频1
思路视频2
代码实现文章


459 重复的子字符串(easy)

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

思路:1.移动匹配 2.kmp

1.移动匹配

当一个字符串s:abcabc,内部由重复的子串组成,那么这个字符串的结构一定是这样的:
在这里插入图片描述
也就是由前后相同的子串组成。

那么既然前面有相同的子串,后面有相同的子串,用 s + s,这样组成的字符串中,后面的子串做前串,前面的子串做后串,就一定还能组成一个s,如图:
在这里插入图片描述
所以判断字符串s是否由重复子串组成,只要两个s拼接在一起,里面还出现一个s的话,就说明是由重复子串组成。

当然,我们在判断 s + s 拼接的字符串里是否出现一个s的的时候,要刨除 s + s 的首字符和尾字符,这样避免在s+s中搜索出原来的s,我们要搜索的是中间拼接出来的s。

2.kmp

在一个串中查找是否出现过另一个串,这是KMP的看家本领。

KMP算法中next数组为什么遇到字符不匹配的时候可以找到上一个匹配过的位置继续匹配,靠的是有计算好的前缀表。 前缀表里,统计了各个位置为终点字符串的最长相同前后缀的长度。

那么 最长相同前后缀和重复子串的关系又有什么关系呢?在由重复子串组成的字符串中,最长相等前后缀不包含的子串就是最小重复子串

代码实现2:

class Solution {
public:bool repeatedSubstringPattern(string s) {string t = s + s;t.erase(t.begin()); t.erase(t.end() - 1); // 掐头去尾if (t.find(s) != std::string::npos) return true; // rreturn false;}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

代码实现2:

class Solution {
public:void getNext (int* next, const string& s){next[0] = 0;int j = 0;for(int i = 1;i < s.size(); i++){while(j > 0 && s[i] != s[j]) {j = next[j - 1];}if(s[i] == s[j]) {j++;}next[i] = j;}}bool repeatedSubstringPattern (string s) {if (s.size() == 0) {return false;}int next[s.size()];getNext(next, s);int len = s.size();if (next[len - 1] != 0 && len % (len - (next[len - 1] )) == 0) {return true;}return false;}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

详细解释:
思路视频
代码实现文章

相关文章:

  • Golang 程序启动原理详解
  • shadertoy 游戏《来自星尘》摇杆复刻
  • tsc : 无法加载文件 C:\Users\Administrat\AppData\Roaming\npm\tsc.ps 1,因为在此系统上禁止运行脚本
  • vmware安装图形版ubuntu(20.4)
  • 【Golang星辰图】探索网络和HTTP的奇妙世界:使用Go语言打造高性能应用
  • 华为配置WLAN高密业务示例
  • 【数据结构】复杂度详解
  • 这里推荐一款unity3d人物动物控制器详细的等学会再写文章
  • 08 OpenCV 腐蚀和膨胀
  • Aws Ec2服务器设置密码登录
  • [DevOps云实践] 彻底删除AWS云资源
  • 【Docker】若依后端项目搭建
  • MariaDB数据库(二)
  • StarRocks——中信建投统一查询服务平台构建
  • MCU设计--M3内核详解(2)
  • (三)从jvm层面了解线程的启动和停止
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • 【技术性】Search知识
  • 2017年终总结、随想
  • C++11: atomic 头文件
  • ComponentOne 2017 V2版本正式发布
  • Debian下无root权限使用Python访问Oracle
  • JAVA并发编程--1.基础概念
  • jQuery(一)
  • Laravel 菜鸟晋级之路
  • MySQL数据库运维之数据恢复
  • Spring Cloud中负载均衡器概览
  • 包装类对象
  • 服务器之间,相同帐号,实现免密钥登录
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 码农张的Bug人生 - 见面之礼
  • 优秀架构师必须掌握的架构思维
  • 由插件封装引出的一丢丢思考
  • 怎么将电脑中的声音录制成WAV格式
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • # Panda3d 碰撞检测系统介绍
  • #include<初见C语言之指针(5)>
  • #LLM入门|Prompt#3.3_存储_Memory
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • (02)vite环境变量配置
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (39)STM32——FLASH闪存
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (pytorch进阶之路)扩散概率模型
  • (附源码)php投票系统 毕业设计 121500
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转) Android中ViewStub组件使用
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .NET BackgroundWorker
  • .NET CORE Aws S3 使用
  • .Net Core 中间件验签