代码随想录算法训练营day9 | 28. 实现 strStr()、459.重复的子字符串

28. 实现 strStr()

暴力解法:双重循环,外层是haystack字符串,内层是needle字符串

KMP算法:当haystack字符串和needle字符串已经匹配部分之后,如果下一个不匹配后,暴力法将会从头开始匹配,已经匹配的部分不能被充分利用

KMP算法能够充分利用已经匹配的部分,首先对needle求最长公共前后缀next,因为对已经匹配上的部分得到最长公共前后缀后可以确定移动位置;然后循环haystack字符串,与needle进行匹配,利用求得的next得到needle下一个匹配的位置

如何求最长公共前后缀
  1. 初始化
  2. 处理前后缀不相同的情况
  3. 处理前后缀相同的情况

使用 前缀表统一减一的方式

初始化
int j = -1;
next[0] = j;

定义两个指针i和j,j指向前缀末尾位置,i指向后缀末尾位置。

next[i] 表示 i(包括i)之前最长相等的前后缀长度(其实就是j)

处理前后缀情况

需要注意:前后缀不相同的情况一定要放在相同的前面,不然有时就会漏处理第一个字符的情况,因为回退到j==-1后需要比较s[i]和s[j + 1]的情况才能确定第一个字符的情况

void getNext(int* next, const string& s){int j = -1;next[0] = j;for(int i = 1; i < s.size(); i++) { // 注意i从1开始while (j >= 0 && s[i] != s[j + 1]) { // 前后缀不相同了j = next[j]; // 向前回退}if (s[i] == s[j + 1]) { // 找到相同的前后缀j++;}next[i] = j; // 将j(前缀的长度)赋给next[i]}
}
字符串与模式串进行匹配

求完最长公共前后缀之后就可以循环haystack字符串,与needle进行匹配

int j = -1; // 因为next数组里记录的起始位置为-1
for (int i = 0; i < s.size(); i++) { // 注意i就从0开始while(j >= 0 && s[i] != t[j + 1]) { // 不匹配j = next[j]; // j 寻找之前匹配的位置}if (s[i] == t[j + 1]) { // 匹配,j和i同时向后移动j++; // i的增加在for循环里}if (j == (t.size() - 1) ) { // 文本串s里出现了模式串treturn (i - t.size() + 1);}
}
前缀表统一减一的方式
class Solution:def strStr(self, haystack: str, needle: str) -> int:next = [-1] * len(needle)self.getNext(needle, next)j = -1for i in range(len(haystack)):while haystack[i] != needle[j + 1] and j >= 0:j = next[j]if haystack[i] == needle[j + 1]:j += 1if j == len(needle) - 1:return i - jreturn -1def getNext(self, s, next):j = -1next[0] = jfor i in range(1, len(s)):while s[j + 1] != s[i] and j >= 0:j = next[j]if s[j + 1] == s[i]:j += 1next[i] = j
前缀表不减一的方式
class Solution:def strStr(self, haystack: str, needle: str) -> int:next = [0] * len(needle)self.getNext(needle, next)j = 0for i in range(len(haystack)):while haystack[i] != needle[j] and j > 0:j = next[j-1]if haystack[i] == needle[j]:j += 1if j == len(needle):return i - j + 1return -1def getNext(self, s, next):j = 0next[0] = jfor i in range(1, len(s)):while s[j] != s[i] and j > 0:j = next[j-1]if s[j] == s[i]:j += 1next[i] = j

注:两种思想是一样的,只是实现有点差别

459.重复的子字符串

两个字符串拼接,去除首尾元素,如果包含原字符串则说明是重复的子字符串

class Solution:def repeatedSubstringPattern(self, s: str) -> bool:# 使用find, s+s,去除第一位和最后一位,还能找到s说明有重复子串if len(s) <= 1:return Falsess = s[1:] + s[:-1]return ss.find(s) != -1

使用KMP算法,推理过程比较复杂,主要在于 next[-1] != -1 and len(s) % (len(s) - (next[-1]+1)) == 0 这一步的判断

class Solution:def repeatedSubstringPattern(self, s: str) -> bool:if len(s) <= 1:return False# 得到next数组next = [-1] * len(s)self.getNext(s, next)if next[-1] != -1 and len(s) % (len(s) - (next[-1]+1)) == 0:return Truereturn Falsedef getNext(self, s, next):j = -1next[0] = jfor i in range(1, len(s)):while s[i] != s[j+1] and j >= 0:j = next[j]if s[i] == s[j+1]:j += 1next[i] = j

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

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

相关文章

使用 Flask 和 WTForms 构建一个用户注册表单

在这篇技术博客中&#xff0c;我们将使用 Flask 和 WTForms 库来构建一个用户注册表单。我们将创建一个简单的 Flask 应用&#xff0c;并使用 WTForms 定义一个注册表单&#xff0c;包括用户名、密码、确认密码、邮箱、性别、城市和爱好等字段。我们还将为表单添加验证规则&…

好用的在线客服系统PHP源码(开源代码+终身使用+安装教程) 制作第一步

创建一个在线客服系统是一个涉及多个步骤的过程&#xff0c;包括前端界面设计、后端逻辑处理、数据库设计、用户认证、实时通信等多个方面。以下是使用PHP制作在线客服系统的第一步&#xff1a;需求分析和系统设计。演示&#xff1a;ym.fzapp.top 第一步&#xff1a;需求分析 确…

分布式技术在文本摘要生成中的应用

摘要 自然语言处理首先要应对的是如何表示文本以供机器处理&#xff0c;随着网络技术的发展和信息的公开&#xff0c;因特网上可供访问的数字文档成爆炸式的增长&#xff0c;文本摘要生成逐渐成为了自然语言处理领域的重要研究课题。本文主要介绍了分布式技术在文本摘要生成中…

基于springboot+vue+Mysql的广场舞团管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

猫头虎分享已解决Bug || TypeError: Cannot read property ‘map‘ of undefined**

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

智慧养猪场视频AI智能监控与可视化管理方案

在科技日新月异的今天&#xff0c;智能化、自动化已成为众多行业追求的方向。养猪业作为传统农业的重要组成部分&#xff0c;同样迎来了技术革新的春风。特别是随着人们对食品安全等问题的日益关注&#xff0c;养猪场视频监控监管方案的智能化升级显得尤为重要。 养猪场视频智…

Android11适配

1.分区存储 1.1.背景 Android 11 进一步增强了平台功能&#xff0c;为外部存储设备上的应用和用户数据提供了更好的保护。作为这项工作的一部分&#xff0c;平台引入了进一步的改进&#xff0c;以简化向分区存储的转换。 为了让用户更好地控制自己的文件&#xff0c;保护用户…

(C++) share_ptr 之循环引用

文章目录 &#x1f6a9;前言&#x1f6a9;循环引用&#x1f579;️例子1Code&#x1f62d;shared_ptr &#xff08;错误&#xff09;&#x1f602;weak_ptr &#xff08;正确&#xff09;&#x1f62d;unique_ptr &#xff08;错误&#xff09; &#x1f579;️例子2Code &…

Vu3+QuaggaJs实现web页面识别条形码

一、什么是QuaggaJs QuaggaJS是一个基于JavaScript的开源图像识别库&#xff0c;可用于识别条形码。 QuaggaJs的作用主要体现在以下几个方面&#xff1a; 实时图像处理与识别&#xff1a;QuaggaJs是一款基于JavaScript的开源库&#xff0c;它允许在Web浏览器中实现实时的图像…

LORA详解

参考论文&#xff1a; low rank adaption of llm 背景介绍&#xff1a; 自然语言处理的一个重要范式包括对一般领域数据的大规模预训练和对特定任务或领域的适应处理。在自然语言处理中的许多应用依赖于将一个大规模的预训练语言模型适配到多个下游应用上。这种适配通常是通过…

初识reactor响应式编程

起源 Reactor响应式编程起源于数据流和变化的传播概念&#xff0c;其核心概念是由底层的执行模型通过数据流自动传播变化。这种编程范式最早由.NET平台上的Reactive Extensions (Rx)库实现&#xff0c;后来迁移到Java平台后&#xff0c;产生了著名的RxJava库&#xff0c;并衍生…

DiT论文精读Scalable Diffusion Models with Transformers CVPR2023

Scalable Diffusion Models with Transformers CVPR2023 Abstract idea 将UNet架构用Transformer代替。并且分析其可扩展性。 并且实验证明通过增加transformer的宽度和深度&#xff0c;有效降低FID 我们最大的DiT-XL/2模型在classconditional ImageNet 512、512和256、256基…

小程序AI智能名片S2B2C商城系统:四大主流商业模式深度解析与实战案例分享

在私域电商迅速崛起的大背景下&#xff0c;小程序AI智能名片S2B2C商城系统以其独特的商业模式和强大的功能&#xff0c;正成为品牌商们争相探索的新领域。在这一系统中&#xff0c;拼团模式、会员电商、社区团购和KOC营销等四种主流模式&#xff0c;为品牌商提供了多样化的营销…

【文章转载】Lance Martin的关于RAG的笔记

转载自微博黄建同学 从头开始学习 RAG&#xff0c;看Lance Martin的这篇笔记就行了&#xff0c;包含了十几篇论文和开源实现&#xff01; —— 这是一组简短的&#xff08;5-10 分钟视频&#xff09;和笔记&#xff0c;解释了我最喜欢的十几篇 RAG 论文。我自己尝试实现每个想…

C# GetField 方法应用实例

目录 关于 C# Type 类 GetField 方法应用 应用举例 心理CT设计题 类设计 DPCT类实现代码 小结 关于 C# Type 类 Type表示类型声明&#xff1a;类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义&#xff0c;以及开放或封闭构造的泛型类型。调用 t…

WPS-EXCEL:快速删除多个线条对象

问题图 我需要将线条快速删除 方法一:使用定位对象功能 使用定位功能&#xff1a;按Ctrl G打开定位对话框。在对话框中&#xff0c;点击“定位条件”。 定位对象&#xff1a;在定位条件对话框中&#xff0c;勾选“对象”选项&#xff0c;然后点击“确定”。这样&#xff0c;…

CTF之变量1

拿到题目发现是一个php代码&#xff0c;意思是用get方式获取args参数。 至于下面那个正则表达式怎么绕过暂且不知&#xff0c;但是题目最上面告诉我们lag In the variable ! &#xff08;意思是flag就在变量中&#xff09;。 那我们就传入全局变量globals&#xff08;&#xf…

spring引入外部属性文件

spring引入外部属性文件 有时候我们并不想把所有的配置信息都放到spring的配置文件中&#xff0c;这样的话也不太好维护&#xff0c;比如说数据库的信息 <bean name"dataSource" class"com.alibaba.druid.pool.DruidDataSource" init-method"init&…

vue调用post方法并且后端代码需要接收ids

首先在ts文件里接收一个参数 data&#xff0c;类型为对象。该函数通过调用 post 函数向指定的路径接口 发送数据 export function calculateScore(data: object) {return post(写你的接口, data) }//以上为举例&#xff0c;calculateScore等会会在vue页面去调用然后我这里做处…

【构建|Gradle】Gradle常见使用问题集锦

文章目录 1. 更新Gradle仓库或者迁移本地Maven仓库后报错2. Gradle配置使用mavenLocal()后,假如添加新的依赖,在Maven仓库中不可见3. 取消使用idea+Gradle创建项目时自动生成.main结尾的子module文章持续更新中。。。 1. 更新Gradle仓库或者迁移本地Maven仓库后报错 错误信息…