代码随想录 Day19 字符串 | LC28 实现strStr() 【KMP经典题目】

六、实现strStr()

题目

力扣28:找出字符串中第一个匹配的下标

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

示例1:

输入:haystack = “sadbutsad”, needle = “sad”
输出:0
解释:“sad” 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。

示例2:

输入:haystack = “leetcode”, needle = “leeto”
输出:-1
解释:“leeto” 没有在 “leetcode” 中出现,所以返回 -1 。

提示:

  • 1 <= haystack.length, needle.length <= 104
  • haystack 和 needle 仅由小写英文字符组成

解题思路分析:


本题是KMP 经典题目。

KMP算法理论基础:

KMP算法的名字由来:

因为是由这三位学者发明的:Knuth,Morris和Pratt,所以取了三位学者名字的首字母。所以叫做KMP。

KMP算法解决的问题:

解决字符串匹配的问题;在文本串种查找是否出现过模式串。

例如:

  • 文本串:aabaabaafa
  • 模式串:aabaaf

暴力匹配: 从下标0处开始,匹配失败后回到下标1处开始重新匹配;时间复杂度为O(m+n)

KMP: 出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。

在这里插入图片描述

前缀表:

KMP可以通过前缀表来做到跳到b直接去继续匹配;

前缀表是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配

前缀:不包含尾字母的所有子串;

  • a;aa;aab;aaba;aabaa

后缀:不包含首字母的所有子串;

  • f;af;aaf;baaf;abaaf

最长相等前后缀:

  • a 最长相等前后缀为0;
  • aa 最长相等前后缀为1;
  • aab 最长相等前后缀为0;
  • aaba 最长相等前后缀为1;
  • aabaa 最长相等前后缀为2;
  • aabaaf 最长相等前后缀为0;

前缀表如下图所示:
在这里插入图片描述

使用前缀表的匹配过程:

当指针移动到f时,发现字符串不匹配,那么就跳到最长相等前缀的后面,也就是跳到最后一个a对应的前缀表数字的位置,即跳到下标为2的位置继续匹配;也就是从b继续匹配。

因为前缀表中的2表示的就是相等前后缀的长度,要跳到前缀的后面,前缀的后面的下标正好就是前缀的长度2。

next数组:

next数组放的也是前缀表,但是可能会有一些调整;

next数组就是遇见冲突以后告诉我们要回退到哪个位置,所以称为next数组。

很多KMP算法具体实现过程中,next数组会把前缀表做一个整体-1的操作;前缀表就变成-1,0,-1,0,1,-1了;但是具体匹配过程中还会做+1操作,原理都是一样的;直接将前缀表原封不动的放入next数组中也能完成匹配。

代码实现:

有的实现是把前缀表整体右移一个位置,第一个位置变成-1;

有的实现是把前缀表整体-1;

在这里插入图片描述

文本串:aabaabaaf

模式串:aabaaf

把前缀表整体右移作为next数组:这种实现方式是直接在遇到冲突的位置也就是f所在位置进行跳转,跳转到b;

也就是在遇见冲突的时候,寻找位置的方式不一样;要么是找冲突位置的前一个位置对应的next数组值;要么就是直接找冲突位置对应的next数组值;原理都是一样的。

获得next数组分为以下几步:

  • 初始化
  • 前后缀不相同
  • 前后缀相同
  • 更新next数组
//初始化
//指针i和指针j;j是指向前缀末尾位置(最长相等前后缀的长度);i是指向后缀末尾位置
int[] next = new int[needle.length()];
int j = 0; //前缀从0开始
next[0] = j;
//求next数组:比较前缀和后缀所对应的字符是否相等,i从1开始才能和j进行比较,所以i初始化为1
for(int i = 1; i < needle.length(); i++) {
  //处理前后缀不相同的情况
  //当needle[i]不等于needle[j]的时候,就相当于在i这个位置发生了冲突,那么j就需要回退到j的前一位对应的next数组的位置;相当于在i这里发生冲突的时候,j回退到j-1对应的next[j-1]的位置,继续重新匹配前后缀
  while(s[i] != s[j]) j = next[j-1];

  //处理前后缀相同的情况
  if(s[i] == s[j]) j++;

  //更新next数组
  next[i] = j;
}

题解:


在这里插入图片描述

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

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

相关文章

全身照怎么缩小做头像?在线图片改大小尺寸的方法

在日常工作中&#xff0c;有不少人喜欢把自己的全身照作为微信或者QQ头像&#xff0c;这时候就经常遇到一个问题&#xff0c;就是图片尺寸太大&#xff0c;无法完整的展现&#xff0c;那么这个时候该怎么处理呢&#xff1f;可以试试下面介绍的这个在线图片改大小尺寸的方法&…

上位机图像处理和嵌入式模块部署(树莓派4b的一种固件部署方法)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 如果软件开发好了之后&#xff0c;下面就是实施和部署。对于树莓派4b来说&#xff0c;部署其实就是烧录卡和拷贝文件。之前我们烧录卡&#xff0c;…

YashanDB连获多项权威认证

近期&#xff0c;YashanDB产品能力再获认可&#xff0c;顺利通过多项权威测试认证&#xff0c;包括通过《数据库政府采购需求标准(2023年版)》测评&#xff1b;通过国密检测机构测试&#xff0c;产品支持GB/T38636-2020《信息安全技术传输层密码协议(TLCP)》国标协议&#xff1…

BRC铭文NFT铸造质押挖矿系统开发运营

区块链技术的不断演进与应用拓展&#xff0c;为数字资产领域带来了更多可能性。BRC铭文NFT铸造质押挖矿系统的开发与运营&#xff0c;将为用户提供一种全新的数字资产体验&#xff0c;下文将介绍其版/需求方案/逻辑项目。 1. 系统概述 BRC铭文NFT铸造质押挖矿系统旨在结合区块…

『docker』 容器虚拟化技术之空间隔离实战

文章目录 容器虚拟化基础之 NameSpaceNameSpace 隔离实战实战目的基础知识dd 命令详解mkfs 命令详解df 命令详解mount 命令详解unshare 命令详解 实战操作一&#xff08;PID 隔离&#xff09;实战操作二&#xff08;Mount 隔离&#xff09; 容器虚拟化基础之 NameSpace 什么是…

RepViT:当MobileNet遇到ViT

paper&#xff1a;https://arxiv.org/abs/2307.09283 code&#xff1a;https://github.com/THU-MIG/RepViT 目录 0. 摘要 1. 引言 2. 相关工作 3. 方法 3.1. 准备工作 3.2. block设计 3.3. 宏观设计 3.4. 微观设计 3.5. 网络结构 4. 实验 4.1. Image Classification …

Day:动态规划 LeedCode 123.买卖股票的最佳时机III 188.买卖股票的最佳时机IV

123. 买卖股票的最佳时机 III 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再次购买前出售掉之前的股票&a…

系统架构设计精华知识

数据流风格&#xff1a;适合于分阶段做数据处理&#xff0c;交互性差&#xff0c;包括&#xff1a;批处理序列、管理过滤器。调用/返回风格&#xff1a;一般系统都要用到&#xff0c;包括&#xff1a;主程序/子程序&#xff0c;面向对象&#xff0c;层次结构&#xff08;分层越…

Rootkit介绍

一、定义 Rootkit是一种恶意软件&#xff0c;旨在让黑客访问和控制目标设备。虽然大多数Rootkit 会影响软件和操作系统&#xff0c;但有些还会感染计算机的硬件和固件。Rootkit善于隐藏自己&#xff0c;担当它们保持隐藏时&#xff0c;其实处于活跃状态。 一旦未经授权获得对计…

让更多的人能使用AI才能提升国内AI竞争力

随着人工智能技术的快速发展,AI正在深入影响我们的生活和工作。然而,目前AI技术的使用和应用主要集中在少数大型科技公司和研究机构,普通大众对AI技术的接触和使用还相对有限。如何让更多的人能够便捷地使用AI,从而带动整个国内AI产业的发展,已成为当前亟需解决的问题。 首先…

SQLAIchemy 异步DBManager封装-03得心应手

前言 SQLAIchemy 异步DBManager封装-01入门理解SQLAIchemy 异步DBManager封装-02熟悉掌握 在前两篇文章中&#xff0c;我们详细介绍了SQLAlchemy异步DBManager的封装过程。第一篇文章帮助我们入门理解了整体的封装结构和思路&#xff0c;第二篇文章则帮助我们更加熟悉和掌握了这…

Github进行fork后如何与原仓库同步

前言 fork了一个仓库以后怎么同步源仓库的代码&#xff1f; 步骤 1、执行命令 git remote -v 查看你的远程仓库的路径。 以一个实际例子说明&#xff0c; 来源仓库&#xff1a; TheFirstLineOfCode/basaltgit remote -v得到&#xff1a; origin https://github.com/ghmi…

“亚马逊依赖”之下,傲基科技的品牌势能如何提升?

受益于出口政策红利、低人工成本、完善的供应链以及成熟的生产工艺优势&#xff0c;近年来我国家具出口行业迅速发展。 数据显示&#xff0c;我国家具出口规模1995年仅为11.06亿美元&#xff0c;至2023年增至641.96亿美元。随着出口规模持续扩大&#xff0c;相关企业积极走入公…

Java高级阶段面试题库(Redis数据库、MQ消息队列、kafka、SpringBoot + SpringCloud、MySQL、JVMJUC、其它)

文章目录 1. Redis数据库篇(忽略)1.1 简单介绍一下redis1.2 单线程的redis为什么读写速度快?1.3 redis为什么是单线程的?1.4 redis服务器的的内存是多大?1.5 为什么Redis的操作是原子性的&#xff0c;怎么保证原子性的&#xff1f;1.6 你还用过其他的缓存吗&#xff1f;这些…

基于深度学习的车牌识别

如果你认为车牌只是车子的‘名字’&#xff0c;那么是时候让你见识一下&#xff0c;当科技赋予它‘超能力’时会发生什么&#xff1f; 上效果图&#xff1b; 这就是车牌识别的力量&#xff0c;下面是主函数代码&#xff1a; # -*- coding: UTF-8 -*- import argparse import …

使用d3.js画一个BoxPlot

Box Plot 在画Box Plot之前&#xff0c;先来了解下Box Plot是什么&#xff1f; 箱线图&#xff08;Box Plot&#xff09;也称盒须图、盒式图或箱型图&#xff0c;是一种用于展示数据分布特征的统计图表。 它由以下几个部分组成&#xff1a; 箱子&#xff1a;表示数据的四分…

阶段性学习汇报 4月19日

目录 一、毕业设计和毕业论文 二、学习python和vue 三、阅读知识图谱 四、下周规划 一、毕业设计和毕业论文 毕业设计后端功能基本实现&#xff0c;但是还有些具体的细节需要优化。前端小程序部分只有个前端页面以及部分交互逻辑&#xff0c;还需进一步完善。在疾病预测这里本…

3d模型合并怎么样不丢材质?---模大狮模型网

在3D设计中&#xff0c;合并模型是常见的操作&#xff0c;它可以帮助设计师将多个单独的模型组合成一个&#xff0c;从而简化场景并提高渲染效率。然而&#xff0c;合并模型时常常会面临一个棘手的问题&#xff1a;如何确保合并后的模型不丢失原有的材质?本文将探讨如何在合并…

电力调度自动化系统由什么构成?

电力调度自动化系统由什么构成&#xff1f; 电力调度自动化系统通过数据采集与传输、数据处理与存储、监视与控制、优化与决策、通信网络和系统应用软件等构成&#xff0c;实现对电力系统的监控、控制和优化。 电力调度自动化系统是一种集成了计算机技术、通信技术、自动化技术…

推荐5款我每次系统重装必装的软件

​ 你电脑中用的最久的软件是哪些&#xff1f;以下是否有你曾经使用过的软件呢&#xff1f;工欲善其事&#xff0c;必先利其器&#xff0c;今天继续分享五款实用的办公软件。 1.素材管理——Billfish ​ Billfish是一款专业的素材管理工具&#xff0c;适用于设计师、摄影师等…