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

【字符串匹配】【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的前缀表:

字符串最长相等前后缀
a0
aa1
aab0
aaba1
aabaa2
aabaaf0

前缀表的任务:当前位置匹配失败,找到之前已经匹配上的位置,再重新匹配。
也意味着在某个字符失配时,前缀表会告诉你下一步匹配中,模式串应该跳到哪个位置。

文本串aabaabaaf
模式串下标012345
模式串aabaaf
–前缀表–010120

当匹配到 b 的时候,模式串为 f ,匹配失败。
于是寻找 f 前面的字符串 aabaa, 他的最长相等前缀和后缀字符串是 aa , 因为找到了最长相等的前缀和后缀,匹配失败的位置是后缀子串的后面,那么我们找到与其相同的前缀的后面(即前缀表中发现冲突位置的前面的字符串——aabaa对应的前缀表为【2】,因此找到模式串中下标索引为【2】的位置 —— b 的位置开始)重新匹配就可以了。

文本串aabaabaaf
模式串aabaaf

(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 找出字符串中第一个匹配项的下标 &#xff08;1&#xff09;前缀和后缀&#xff08;2&#xff09;前缀表&#xff08;最长相同的前缀和后缀的长度&#xff09;&#xff08;3&#xff09;匹配过程示意&#xff08;4&#xff09;next数组的…...

《洛谷深入浅出进阶篇》模意义下的乘法逆元+洛谷P3811

什么是乘法逆元&#xff1f; 算数意义上的乘法逆元指的是倒数&#xff0c;即&#xff1a;a*&#xff08;1/a&#xff09;1 所以 1/a 是 a在算数意义下的乘法逆元&#xff0c;或者可以说二者互为逆元。 这有什么用呢&#xff1f; 除以a就等于乘上a的乘法逆元&#xff0c;乘以…...

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. 解码方法&#xff1a;样例 1&#xff1a;样例 2&#xff1a;样例 3&#xff1a;提示&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 91. 解码方法&#xff1a; 一条包含字母 A-Z…...

zabbix配置snmp trap--使用snmptrapd和Bash接收器(缺zabbix_trap_handler.sh文中自取)--图文教程

1.前言 我的zabbix的版本是5.0版本&#xff0c;5.0的官方文档没有使用bash接收器的示例&#xff0c;6.0的官方文档有使用bash接收器的示例&#xff0c;但是&#xff0c;下载文件的链接失效&#xff1f;&#xff01; 这里讲解zabbix-server端配置和zabbix web端配置 2.zabbix-…...

vue: 线上项目element-ui的icon偶尔乱码问题

线上环境偶尔会复现&#xff0c; 具体&#xff1a; 一般使用不会出现这个问题&#xff0c;因为一般引入的是element-ui的css文件&#xff0c;问题出在于为了主题色变化啊&#xff0c;需要用到scss变量引入了scss文件。 import “~element-ui/packages/theme-chalk/src/index”…...

fpga rom 初始化文件的一些心得

目录 可能遇到的问题 问题 解决方案 rom的初始化 用途 文件类型 如何生成初始化文件 示例 Altera Xilinx 可能遇到的问题 问题 altera FPGA的rom找不到初始化文件&#xff0c;编译过程会提示类似的问题 Error(127001): Cant find Memory Initialization File or He…...

从零构建属于自己的GPT系列3:模型训练2(训练函数解读、模型训练函数解读、代码逐行解读)

&#x1f6a9;&#x1f6a9;&#x1f6a9;Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1&#xff1a;文本数据预处理 从零构建属于自己的GPT系列2&#xff1a;语…...

Python词频统计(数据整理)

请编写程序&#xff0c;对一段英文文本&#xff0c;统计其中所有不同单词的个数&#xff0c;以及词频最大的前10%的单词。 输入格式: 输入给出一段非空文本&#xff0c;最后以符号#结尾。输入保证存在至少10个不同的单词。 输出格式: 在第一行中输出文本中所有不同单词的个数…...

基本面选股的方法

基本面选股是一种投资策略&#xff0c;主要关注公司的财务状况、盈利能力、行业地位等因素&#xff0c;以判断公司的价值并做出投资决策。以下是基本面选股的具体分析方法和重点&#xff1a; 财务状况分析&#xff1a; 利润表分析&#xff1a;关注公司的净利润、毛利率、营业…...

应用密码学期末复习(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平板签约投屏-高端活动的选择

传统的现场纸质签约仪式除了缺乏仪式感之外还缺少互动性&#xff0c;如果要将签约的过程投放到大屏幕上更是需要额外的硬件设备成本。相比于传统的纸质签约仪式&#xff0c;平板现场电子签约的形式更加的新颖、更富有科技感、更具有仪式感。 平板签约投屏是应用于会议签字仪式的…...

分布式架构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学习研究笔记&#xff08;二&#xff09;——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函数参数&#xff08;代码&#x…...

牛客java基础考点1 标识符和变量

牛客java基础考点1 标识符和变量 标识符 字母和数字&#xff1a; 标识符由字母、数字、下划线&#xff08;_&#xff09;和美元符号&#xff08;$&#xff09;组成。其中&#xff0c;标识符必须以字母、下划线或美元符号开头。大小写敏感&#xff1a; Java 是大小写敏感的语言…...

Qt将打印信息输出到文件

将打印信息&#xff08;qDebug、qInfo、qWarning、qCritial等&#xff09;输出到指定文件来以实现简单的日志功能。 #include "mainwindow.h" #include <QApplication> #include <QLoggingCategory> #include <QMutex> #include <QDateTime>…...

【risc-v】易灵思efinix FPGA sapphire_soc IP配置参数分享

系列文章目录 分享一些fpga内使用riscv软核的经验&#xff0c;共大家参考。后续内容比较多&#xff0c;会做成一个系列。 本系列会覆盖以下FPGA厂商 易灵思 efinix 赛灵思 xilinx 阿尔特拉 Altera 本文内容隶属于【易灵思efinix】系列。 前言 在efinix fpga中使用riscv是一…...

直播的种类及类型

随着网络技术和移动设备的普及&#xff0c;直播已经成为人们娱乐、学习、商业交流等众多领域的重要工具。 直播的种类主要有以下几种: 1.视频直播:这是最常见的直播形式&#xff0c;包括电商直播、婚庆直播、培训直播、家居直播等。 2.图文直播:这种直播形式包括PPT互动直播…...

时间序列数据压缩算法简述

本文简单介绍了时间序列压缩任务的来源&#xff0c;压缩算法的分类&#xff0c;并对常见压缩算法的优缺点进行了简介&#xff0c;爱码士们快来一探究竟呀&#xff01; 引言 时间序列数据是在许多应用程序和领域中生成的一种基本数据类型&#xff0c;例如金融、医疗保健、交通和…...

智能锁-SI522TORC522方案资料

南京中科微这款SI522目前完全PinTOPin兼容的NXP&#xff1a;RC522、CV520 复旦微&#xff1a;FM17520、FM17522/FM17550 瑞盟&#xff1a;MS520、MS522 国民技术:NZ3801、NZ3802 SI522 是应用于13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员。是NXP 公司针对&quo…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...