【字符串匹配】【KMP算法】Leetcode 28 找出字符串中第一个匹配项的下标☆
【字符串匹配】【KMP算法】Leetcode 28 找出字符串中第一个匹配项的下标
- (1)前缀和后缀
- (2)前缀表(最长相同的前缀和后缀的长度)
- (3)匹配过程示意
- (4)next数组的实现方法
- 1.初始化
- 2.处理前后缀不相等的情况 :
- 3.处理前后缀相同的情况:
- 4.求next数组的程序:
- 题目做法
- 解法1 KMP算法
- 解法2 暴力做法
---------------🎈🎈题目链接🎈🎈-------------------

🔴任务:要在文本串:aabaabaafa 中查找是否出现过一个模式串:aabaaf
(1)前缀和后缀
前缀是指不包含最后一个字符的,所有以第一个字符开头的连续子串。
比如aabaaf的前缀包括:a,aa,aab,aaba,aabaa
后缀是指不包含第一个字符的,所有以最后一个字符结尾的连续子串。
比如aabaaf的后缀包括:f,af,aaf,baaf,abaaf
(2)前缀表(最长相同的前缀和后缀的长度)
前缀表(最长相同的前缀和后缀的长度)
前缀表(最长相同的前缀和后缀的长度)
前缀表(最长相同的前缀和后缀的长度)
作用:记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀
模式串aabaaf的前缀表:
| 字符串 | 最长相等前后缀 |
|---|---|
| a | 0 |
| aa | 1 |
| aab | 0 |
| aaba | 1 |
| aabaa | 2 |
| aabaaf | 0 |
前缀表的任务:当前位置匹配失败,找到之前已经匹配上的位置,再重新匹配。
也意味着在某个字符失配时,前缀表会告诉你下一步匹配中,模式串应该跳到哪个位置。
| 文本串 | a | a | b | a | a | b | a | a | f |
|---|---|---|---|---|---|---|---|---|---|
| 模式串下标 | 0 | 1 | 2 | 3 | 4 | 5 | |||
| 模式串 | a | a | b | a | a | f | |||
| –前缀表– | 0 | 1 | 0 | 1 | 2 | 0 |
当匹配到 b 的时候,模式串为 f ,匹配失败。
于是寻找 f 前面的字符串 aabaa, 他的最长相等前缀和后缀字符串是 aa , 因为找到了最长相等的前缀和后缀,匹配失败的位置是后缀子串的后面,那么我们找到与其相同的前缀的后面(即前缀表中发现冲突位置的前面的字符串——aabaa对应的前缀表为【2】,因此找到模式串中下标索引为【2】的位置 —— b 的位置开始)重新匹配就可以了。
| 文本串 | a | a | b | a | a | b | a | a | f |
|---|---|---|---|---|---|---|---|---|---|
| 模式串 | a | a | b | a | a | f |
(3)匹配过程示意

(4)next数组的实现方法
next数组详解视频!
代码随想录文字版
!!!!!代码随想录视频版本!!!!!
1.初始化
【i:后缀的末尾】初始化为1,
【j:前缀的末尾】初始化为0 , next [ 0 ] = 0
j:也代表了i包括i之前的字符串的最长相等前后缀长度
2.处理前后缀不相等的情况 :
j连续回退 ———— j=next [ j-1 ], (在j大于0的情况下)
3.处理前后缀相同的情况:
j++ → 更新next数组:next [ i ] = j → i++
4.求next数组的程序:
1.初始化 【i:后缀的末尾】初始化为1, 【j:前缀的末尾,也代表i包括i前字符的最长相等前后缀长度】初始化为0 , next[0] = 0
2.处理前后缀不相等的情况
3.处理前后缀相同的情况//求前缀表nextprivate void getNext(int[] next, String s){int j = 0; // 初始化j为前缀末尾0,i为后缀的末尾next[0] = 0;for(int i = 1; i < s.length(); i++){ while(j > 0 && s.charAt(j) != s.charAt(i)){ j = next[j-1];}if(s.charAt(j) == s.charAt(i)){ // 如果相同,前缀末尾j++j++;}next[i] = j; // 将前缀的长度给next[i]}}
题目做法
解法1 KMP算法
时间复杂度O(N)
空间复杂度O(N)
class Solution {public int strStr(String haystack, String needle) {if(haystack.length() < needle.length()) return -1;int[] next = new int[needle.length()];getNext(next, needle);int j = 0;for(int i = 0; i < haystack.length(); i++){while(j>0 && needle.charAt(j) != haystack.charAt(i)){ j = next[j-1];}if(needle.charAt(j) == haystack.charAt(i)){j++;}if(j == needle.length()) {return i-needle.length()+1;}}return -1;}//求前缀表nextprivate void getNext(int[] next, String s){int j = 0; // 初始化j为前缀末尾0,i为后缀的末尾next[0] = 0;for(int i = 1; i < s.length(); i++){ while(j > 0 && s.charAt(j) != s.charAt(i)){ j = next[j-1];}if(s.charAt(j) == s.charAt(i)){ // 如果相同,前缀末尾j++j++;}next[i] = j; // 将前缀的长度给next[i]}}
}
解法2 暴力做法
从大字符串的第一个元素开始,比对小字符串,一旦出现不一样的就从大字符串的下一个元素开始进行比对
如果小字符串遍历结束时都一样,则return对应的下标
如果大字符串遍历完小字符串还没遍历完,return-1
遍历完大字符串前都找不到的话就return -1
时间复杂度O(N^2)
空间复杂度O(N)
class Solution {public int strStr(String haystack, String needle) {// 暴力做法char[] ch1 = haystack.toCharArray();char[] ch2 = needle.toCharArray();int result = -1;for(int i = 0; i < ch1.length; i++){ // haystack的遍历if(ch1[i] == ch2[0]){int outside = i;int inside = 0;while(ch1[outside] == ch2[inside]){outside++;inside++;if(inside == ch2.length){return outside-ch2.length;}else if(outside == ch1.length){return result;}}}}return result;}
}
相关文章:
【字符串匹配】【KMP算法】Leetcode 28 找出字符串中第一个匹配项的下标☆
【字符串匹配】【KMP算法】Leetcode 28 找出字符串中第一个匹配项的下标 (1)前缀和后缀(2)前缀表(最长相同的前缀和后缀的长度)(3)匹配过程示意(4)next数组的…...
《洛谷深入浅出进阶篇》模意义下的乘法逆元+洛谷P3811
什么是乘法逆元? 算数意义上的乘法逆元指的是倒数,即:a*(1/a)1 所以 1/a 是 a在算数意义下的乘法逆元,或者可以说二者互为逆元。 这有什么用呢? 除以a就等于乘上a的乘法逆元,乘以…...
clickhouse -- clickhouse解析复杂JSON数组
举例 - 查数据 select _id,doctorId,patientId,diagnosisList from patient_disease final where diagnosisList is not null limit 3;- 解析数组 SELECT _id,doctorId,patientId,visitParamExtractRaw(diagnosisList,diagnosisName) FROM patient_disease final where _id …...
算法leetcode|91. 解码方法(rust重拳出击)
文章目录 91. 解码方法:样例 1:样例 2:样例 3:提示: 分析:题解:rust:go:c:python:java: 91. 解码方法: 一条包含字母 A-Z…...
zabbix配置snmp trap--使用snmptrapd和Bash接收器(缺zabbix_trap_handler.sh文中自取)--图文教程
1.前言 我的zabbix的版本是5.0版本,5.0的官方文档没有使用bash接收器的示例,6.0的官方文档有使用bash接收器的示例,但是,下载文件的链接失效?! 这里讲解zabbix-server端配置和zabbix web端配置 2.zabbix-…...
vue: 线上项目element-ui的icon偶尔乱码问题
线上环境偶尔会复现, 具体: 一般使用不会出现这个问题,因为一般引入的是element-ui的css文件,问题出在于为了主题色变化啊,需要用到scss变量引入了scss文件。 import “~element-ui/packages/theme-chalk/src/index”…...
fpga rom 初始化文件的一些心得
目录 可能遇到的问题 问题 解决方案 rom的初始化 用途 文件类型 如何生成初始化文件 示例 Altera Xilinx 可能遇到的问题 问题 altera FPGA的rom找不到初始化文件,编译过程会提示类似的问题 Error(127001): Cant find Memory Initialization File or He…...
从零构建属于自己的GPT系列3:模型训练2(训练函数解读、模型训练函数解读、代码逐行解读)
🚩🚩🚩Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1:文本数据预处理 从零构建属于自己的GPT系列2:语…...
Python词频统计(数据整理)
请编写程序,对一段英文文本,统计其中所有不同单词的个数,以及词频最大的前10%的单词。 输入格式: 输入给出一段非空文本,最后以符号#结尾。输入保证存在至少10个不同的单词。 输出格式: 在第一行中输出文本中所有不同单词的个数…...
基本面选股的方法
基本面选股是一种投资策略,主要关注公司的财务状况、盈利能力、行业地位等因素,以判断公司的价值并做出投资决策。以下是基本面选股的具体分析方法和重点: 财务状况分析: 利润表分析:关注公司的净利润、毛利率、营业…...
应用密码学期末复习(3)
目录 第三章 现代密码学应用案例 3.1安全电子邮件方案 3.1.1 PGP产生的背景 3.2 PGP提供了一个安全电子邮件解决方案 3.2.1 PGP加密流程 3.2.2 PGP解密流程 3.2.3 PGP整合了对称加密和公钥加密的方案 3.3 PGP数字签名和Hash函数 3.4 公钥分发与认证——去中心化模型 …...
PAD平板签约投屏-高端活动的选择
传统的现场纸质签约仪式除了缺乏仪式感之外还缺少互动性,如果要将签约的过程投放到大屏幕上更是需要额外的硬件设备成本。相比于传统的纸质签约仪式,平板现场电子签约的形式更加的新颖、更富有科技感、更具有仪式感。 平板签约投屏是应用于会议签字仪式的…...
分布式架构demo
1、外层创建pom 版本管理器 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.15</version><relativePath/> <!-- lookup parent from repository…...
TA-Lib学习研究笔记(二)——Overlap Studies上
TA-Lib学习研究笔记(二)——Overlap Studies 1. Overlap Studies 指标 [BBANDS, DEMA, EMA, HT_TRENDLINE, KAMA, MA, MAMA, MAVP, MIDPOINT, MIDPRICE, SAR, SAREXT, SMA, T3, TEMA, TRIMA, WMA]2.数据准备 get_data函数参数(代码&#x…...
牛客java基础考点1 标识符和变量
牛客java基础考点1 标识符和变量 标识符 字母和数字: 标识符由字母、数字、下划线(_)和美元符号($)组成。其中,标识符必须以字母、下划线或美元符号开头。大小写敏感: Java 是大小写敏感的语言…...
Qt将打印信息输出到文件
将打印信息(qDebug、qInfo、qWarning、qCritial等)输出到指定文件来以实现简单的日志功能。 #include "mainwindow.h" #include <QApplication> #include <QLoggingCategory> #include <QMutex> #include <QDateTime>…...
【risc-v】易灵思efinix FPGA sapphire_soc IP配置参数分享
系列文章目录 分享一些fpga内使用riscv软核的经验,共大家参考。后续内容比较多,会做成一个系列。 本系列会覆盖以下FPGA厂商 易灵思 efinix 赛灵思 xilinx 阿尔特拉 Altera 本文内容隶属于【易灵思efinix】系列。 前言 在efinix fpga中使用riscv是一…...
直播的种类及类型
随着网络技术和移动设备的普及,直播已经成为人们娱乐、学习、商业交流等众多领域的重要工具。 直播的种类主要有以下几种: 1.视频直播:这是最常见的直播形式,包括电商直播、婚庆直播、培训直播、家居直播等。 2.图文直播:这种直播形式包括PPT互动直播…...
时间序列数据压缩算法简述
本文简单介绍了时间序列压缩任务的来源,压缩算法的分类,并对常见压缩算法的优缺点进行了简介,爱码士们快来一探究竟呀! 引言 时间序列数据是在许多应用程序和领域中生成的一种基本数据类型,例如金融、医疗保健、交通和…...
智能锁-SI522TORC522方案资料
南京中科微这款SI522目前完全PinTOPin兼容的NXP:RC522、CV520 复旦微:FM17520、FM17522/FM17550 瑞盟:MS520、MS522 国民技术:NZ3801、NZ3802 SI522 是应用于13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员。是NXP 公司针对&quo…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
