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

28. 找出字符串中第一个匹配项的下标【 力扣(LeetCode) 】

一、题目描述

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

二、测试用例

示例 1:

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

示例 2:

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

提示:

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

三、解题思路

  1. 基本思路:
      采用KMP算法;
  2. 具体思路:
    • 计算 next 数组:可以暴力计算,也可以优化方法;这里介绍优化方法:
      • next[0]next[1] 必定为 0 ,从 next[2] 开始计算。next[i] 表示前 i 个字母相同,第 i+1 个字母不同时,应该跳转的位置。 例如:在这里插入图片描述
          以 i=4 为例,表示前 4 个字母相同,但第 5 个字母不同,正常情况下,匹配字符串 ABCABD 匹配到第 5 个字母 B 时遇到不匹配字母时,则要从头即 A 开始重新匹配,但是其实我们已经匹配过前 4 个字母,我们知道前 4 个字母的情况,即待匹配序列为 …ABCA#**** 的形式,我们可以不需要返回从 A 开始,可以直接从 # 位置开始与匹配字符串的第二个字母 B 进行匹配,即 next 可以不用等于 0 ,可以等于 1 。【第一个字母下标 0,第二个字母下标为 1】
      • ② 定义变量 p ,表示相同前缀下标,初始化为 0 ;定义变量 i ,用于遍历 next 数组,初始化为 2 ;
      • ③ 判断 needle[i-1]needle[p] 是否相等,相等表示他们有相同的前缀,则将 p+1 的值赋值给 next[i] ;否则,表示他们前缀不同,则判断 p 是否等于 0 ,等于 0 表示不存在相同的前缀,则 next = 0 ,不等于 0 表示可能存在相同前缀,令 p = next[p] ,继续寻找相同前缀;
    • 进行匹配:
      • ① 定义变量 i 和 j ,用于遍历待匹配字符串和匹配字符串,初始化都为 0 ;
      • ② 遍历字符串,如果两个字母相同,则匹配下一个字母,如果匹配字符串都匹配完,则返回下标;如果字母不同,则判断是否为匹配字符串的第一个字母,是则表示第一个字母都不一样,则待匹配字符串下移一个字母,不是则表示可能存在匹配前缀,匹配字符串根据 next 数组移动要对应位置。遍历结束则表示不存在匹配的字符串,则返回 -1 。

四、参考代码

时间复杂度: O ( n + m ) \Omicron(n+m) O(n+m) 【 m 为待匹配字符串长度,n 为匹配字符串长度】
空间复杂度: O ( n ) \Omicron(n) O(n)

class Solution {
public:void setNext(vector<int> &next,string needle){int n=next.size();int p=0;next[0]=next[1]=0;for(int i=2;i<n;){if(needle[i-1]==needle[p]){next[i++]=++p;}else{if(p==0){next[i++]=0;}else{p=next[p];}}}}int strStr(string haystack, string needle) {int n=needle.size();int m=haystack.size();int j=0;vector<int> next(n+1,0);setNext(next,needle);for(int i=0;i<m;){if(haystack[i]==needle[j]){j++;i++;if(j==n){return i-j;}}else{if(j==0)i++;j=next[j];}}return -1;}
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【知识点介绍】时钟置换算法(CLOCK算法)
  • 【python学习】深入解析 `jq` 库:JSON 处理的利器
  • 数据库(一):MySQL概述
  • Spring Boot + Vue 跨域配置(CORS)问题解决历程
  • 构建智能生态,视频监控/安防监控EasyCVR视频汇聚流媒体技术在智能分析领域的应用
  • 《TOGAF®标准第10版》:企业架构新时代的必备指南与实践蓝图
  • JS【详解】 延迟加载
  • 阿里云服务器 ECS部署jenkins
  • 《企业净零排放实用手册》:助力中小企业实现“双碳”目标
  • 工业智能网关在汽车制造企业的应用价值及功能-天拓四方
  • EVAL长度突破限制
  • Golang 并发编程
  • 【相机与图像】2. 相机内外参的标定的代码示例
  • 中国科技统计年鉴,数据覆盖1991-2022年多年份
  • 基于Python大数据的电商产品评论的情感分析设计与实现,包括lda主题分析和情感分析
  • 自己简单写的 事件订阅机制
  • chrome扩展demo1-小时钟
  • ComponentOne 2017 V2版本正式发布
  • EOS是什么
  • HTTP 简介
  • JAVA SE 6 GC调优笔记
  • JavaScript的使用你知道几种?(上)
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • Java精华积累:初学者都应该搞懂的问题
  • LeetCode算法系列_0891_子序列宽度之和
  • Meteor的表单提交:Form
  • MobX
  • python3 使用 asyncio 代替线程
  • rc-form之最单纯情况
  • React组件设计模式(一)
  • 初识 beanstalkd
  • 基于 Babel 的 npm 包最小化设置
  • 悄悄地说一个bug
  • 实战|智能家居行业移动应用性能分析
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • # 利刃出鞘_Tomcat 核心原理解析(八)-- Tomcat 集群
  • # 数论-逆元
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (2024,Vision-LSTM,ViL,xLSTM,ViT,ViM,双向扫描)xLSTM 作为通用视觉骨干
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (一)Java算法:二分查找
  • (原)Matlab的svmtrain和svmclassify
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • ***通过什么方式***网吧
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .Net MVC4 上传大文件,并保存表单
  • .net/c# memcached 获取所有缓存键(keys)
  • .NET简谈设计模式之(单件模式)