力扣面试经典题 | 找出字符串中第一个匹配项的下标

力扣面试经典题 | 找出字符串中第一个匹配项的下标

  • 题目描述
  • 解题思路
    • 构建next数组
    • 使用next数组来做匹配
  • 代码实现

题目描述

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算法经典题目。

构建next数组

定义一个函数getNext来构建next数组,函数参数为指向next数组的指针,和一个字符串。 代码如下:

void getNext(int* next, const string& s) {}
  1. 初始化
    定义两个指针i和j,j指向前缀末尾位置,i指向后缀末尾位置。
    然后还要对next数组进行初始化赋值,如下:
    int j = -1;
    next[0] = j;
    
  2. 处理前后缀不相同的情况
    因为j初始化为-1,那么i就从1开始,进行s[i] 与 s[j+1]的比较。所以遍历模式串s的循环下标i 要从 1开始,代码如下:
    for (int i = 1; i < s.size(); i++) {}
    
    如果 s[i] 与 s[j+1]不相同,也就是遇到 前后缀末尾不相同的情况,就要向前回退。而next[j]就是记录着j(包括j)之前的子串的相同前后缀的长度。
    那么 s[i] 与 s[j+1] 不相同,就要找 j+1前一个元素在next数组里的值(就是next[j])。
    所以,处理前后缀不相同的情况代码如下:
while (j >= 0 && s[i] != s[j + 1]) { // 前后缀不相同j = next[j]; // 向前回退
}
  1. 处理前后缀相同的情况
    如果 s[i] 与 s[j + 1] 相同,那么就同时向后移动i 和j 说明找到了相同的前后缀,同时还要将j(前缀的长度)赋给next[i], 因为next[i]要记录相同前后缀的长度。
    if (s[i] == s[j + 1]) { // 前后缀相同j++;
    }
    next[i] = j;
    

最后构建next数组的整体代码如下:

void getNext(int* next, const string& s) {int j = -1;next[0] = j;for (int i = 1; i < s.size(); i++) {while (j >= 0 && s[i] != s[j + 1]) { // 前后缀不相同j = next[j]; // 向前回退}if (s[i] == s[j + 1]) { // 找到相同的前后缀j++;}next[i] = j; // 将前缀的长度 j 赋给next[i]}
}

使用next数组来做匹配

在文本串 s 中寻找 格式串 t

定义两个下标,j 指向模式串起始位置,i 指向文本串起始位置。

j 初始值依然为-1,因为next数组里记录的起始位置为-1。

i就从0开始,遍历文本串,代码如下:

for (int i = 0; i < s.size(); i++) {}

接下来就是 s[i] 与 t[j + 1] (因为j从-1开始的) 进行比较。

如果 s[i] 与 t[j + 1] 不相同,j就要从next数组里寻找下一个匹配的位置。

代码如下:

while(j >= 0 && s[i] != t[j + 1]) {j = next[j];
}

如果 s[i] 与 t[j + 1] 相同,那么i 和 j 同时向后移动, 代码如下:

if (s[i] == t[j + 1]) {j++; // i的增加在for循环里
}

如果j指向了模式串t的末尾,那么就说明模式串t完全匹配文本串s里的某个子串了。

本题要在文本串字符串中找出模式串出现的第一个位置 (从0开始),所以返回当前在文本串匹配模式串的位置i 减去 模式串的长度,就是文本串字符串中出现模式串的第一个位置。

if (j == (t.size() - 1) ) {return (i - t.size() + 1);
}

整体代码如下:

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 {
public: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]}}int strStr(string haystack, string needle) {if (needle.size() == 0) {return 0;}int next[needle.size()];getNext(next, needle);int j = -1; // // 因为next数组里记录的起始位置为-1for (int i = 0; i < haystack.size(); i++) { // 注意i就从0开始while(j >= 0 && haystack[i] != needle[j + 1]) { // 不匹配j = next[j]; // j 寻找之前匹配的位置}if (haystack[i] == needle[j + 1]) { // 匹配,j和i同时向后移动j++; // i的增加在for循环里}if (j == (needle.size() - 1) ) { // 文本串s里出现了模式串treturn (i - needle.size() + 1);}}return -1;}
};

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

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

相关文章

CTF V8 pwn入门(一)

仍然是因为某些原因&#xff0c;需要学学浏览器pwn 环境 depot_tools建议直接去gitlab里下&#xff0c;github上这个我用魔法都没下下来 下完之后执行 echo export PATH$PATH:"/root/depot_tools" >> ~/.bashrc路径换成自己的就ok了 然后是ninja git clo…

Helm 包管理器

一、什么是 Helm&#xff1f; Kubernetes 包管理器 Helm 是查找、分享和使用软件构件 Kubernetes 的最优方式。Helm 管理名为 chart 的 Kubernetes 包的工具。Helm 可以做以下的事情&#xff1a; 从头开始创建新的 chart 将 chart 打包成归档(tgz)文件 与存储 chart 的仓库进行…

《opencv实用探索·十七》calcBackProject直方图反向投影

在了解反向投影前需要先了解下直方图的概念&#xff0c;可以看我上一章内容&#xff1a;opencv直方图计算calcHist函数解析 直方图反向投影是一种图像处理技术&#xff0c;通常用于目标检测和跟踪。通过计算反向投影&#xff0c;可以将图像中与给定模式&#xff08;目标对象&a…

c++ map

unordered_map #include <iostream> #include <string> #include <unordered_map>int main() {// 创建包含三个字符串的&#xff08;映射到字符串的&#xff09;unordered_mapstd::unordered_map<std::string, std::string> u {{"red", &qu…

《opencv实用探索·十八》Camshift进行目标追踪流程

CamShift&#xff08;Continuously Adaptive Mean Shift&#xff09;是一种用于目标跟踪的方法&#xff0c;它是均值漂移&#xff08;Mean Shift&#xff09;的扩展&#xff0c;支持对目标的旋转跟踪&#xff0c;能够对目标的大小和形状进行自适应调整。 cv::CamShift和cv::me…

焦炭冶金工艺3D可视化仿真展示更直观、形象

冶金行业作为重要的工业领域&#xff0c;其岗位实践培训一直面临着诸多挑战&#xff0c;随着web3d开发和VR虚拟仿真技术的不断创新和应用&#xff0c;冶金3D虚拟仿真实践教学平台应运而生&#xff0c;为钢铁生产培训带来了崭新的变革。 冶金3D虚拟仿真实践教学平台采用了先进的…

【CANN训练营】高阶笔记

Ascend C Tilling计算 Tilling基本概念介绍 大多数情况下&#xff0c;Local Memory的存储&#xff0c;无法完全容纳算子的输入与输出的所有数据&#xff0c;需要每次搬运一部分输入数柜进行计算然后搬出&#xff0c;再敲运下一部分输入数据进行计算&#xff0c;直到得到完愁的…

GoEasy使用手册

GoEasy官网 登录 - GoEasy 即时通讯聊天案例 GoEasy - GoEasy (gitee.com) 注意事项 接口使用人数上限为15&#xff0c;超出之后会请求超时返回408状态码&#xff0c;可以新建一个应用用来更换common Key 创建应用 ​ 添加应用名称&#xff0c;其余默认&#xff0c;点击…

算法通关村第十三关—数学与数学基础问题(青铜)

数学与数学基础问题 一、统计专题 1.1 符号统计 LeetCode1822给定一个数组&#xff0c;求所有元素的乘积的符号&#xff0c;如果最终答案是负的返回-1&#xff0c;如果最终答案是正的返回1&#xff0c;如果答案是0返回0。  题目比较简单&#xff0c;正数对结果完全没影响&…

CVE-2021-4145:类型混淆导致释放任意 file 结构体

前言 影响版本&#xff1a; v5.13.4 之前 测试版本&#xff1a;v5.13.3 &#xff08;感谢 bsauce 大佬提供的测试环境&#xff09; 漏洞发生在 fsconfig 处理时调用的cgroup1_parse_param 函数中&#xff0c;patch&#xff1a; diff --git a/kernel/cgroup/cgroup-v1.c b/k…

软路由R4S+iStoreOS如何实现公网远程桌面本地电脑

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、Cpolar杂谈 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. 简介1.1 软路由的定义1.2 使用软路由的好处1.3 常用组网 二. 配置远程桌面公网地址三. 家中使用…

mysql原理--B+树索引的使用

1.索引的代价 在介绍如何更好的使用索引之前先要了解一下使用这玩意儿的代价&#xff0c;它在空间和时间上都会拖后腿&#xff1a; (1). 空间上的代价 这个是显而易见的&#xff0c;每建立一个索引都要为它建立一棵 B 树&#xff0c;每一棵 B 树的每一个节点都是一个数据页&…

简单的小题集(八)

文章目录 一、这题有点麻烦二、Nba 总冠军 2 一、这题有点麻烦 信不信这道题的核心内容连两句话都没有&#xff0c;说实话&#xff0c;就这不到两句话的题就能 把你做熄火了&#xff0c;不信你就试试呗&#xff1a; 皮皮的小南教大家玩数字&#xff0c;这不他拿出 n 个数字&am…

抖去推--短视频剪辑、矩阵无人直播saas营销工具一站式开发

抖去推是一款短视频剪辑和矩阵无人直播SAAS营销工具一站式开发平台。它提供了以下功能和特点&#xff1a; 1. 短视频剪辑&#xff1a;抖去推提供了一系列的剪辑工具&#xff0c;包括自动剪辑、特效制作、配音配乐等&#xff0c;可以帮助用户轻松制作出高质量的短视频。 2. 矩阵…

Python多线程thread与子线程

Python多线程Thread——生产者消费者模型-CSDN博客 python队列与多线程——生产者消费者模型-CSDN博客 import random import threading import time# 主线程 class MainThread(threading.Thread):def __init__(self, name, num0, target10):super(MainThread, self).__init_…

日志审计在网络安全中的重要性

日志审计是一种通过分析、识别和验证各种日志信息&#xff0c;以帮助企业了解其网络和系统的安全状态和活动的过程。这些日志信息可能来自各种来源&#xff0c;包括服务器、网络设备、应用程序、操作系统等。 日志审计的主要功能包括&#xff1a; 1.识别潜在的安全威胁&#…

创建第一个Vue2项目-----HelloWorld

创建第一个Vue项目 第一步先去安装Vue&#xff0c;一共有两种安装方式&#xff0c;这里使用 点击这里下载&#xff1a;Vue.js 添加到自己的项目中 在使用的页面引入<script src"../js/vue.js"></script> 2. 准备好一个容器 <div id"root&qu…

阿里云大数据工程师ACP认证,今天终于搞定了,87分

为啥我得去考个阿里云大数据工程ACP证书&#xff1f; 首先得声明&#xff0c;这不是因为我对阿里有多痴迷&#xff0c;也不是因为我想把我的简历装饰得花里胡哨。实际上&#xff0c;这更像是一场自我挑战的游戏。我就是一根筋&#xff0c;当时公司要求考阿里云大数据工程师认证…

Redis部署-集群

目录 集群 数据分片算法 哈希求余 一致性哈希算法 哈希槽分区算法 redis集群搭建 1.创建目录和配置. 2.将上述redis节点.构建成集群 3.使用客户端连接集群 集群模式下的故障转移流程 1.故障判定 2.故障迁移 集群扩容 集群 广义上的集群,只要是多个机器,构成了分布…

axios无法获取response headers中的内容

前言 后端在响应头中加了些参数&#xff0c;前端发起axios请求&#xff0c;在浏览器中发现这些参数在response headers中返回了&#xff08;能看到&#xff09;&#xff0c;但是axios取不到&#xff01; 好久之前遇到过这个问题&#xff0c;解决过但是没有记录&#xff0c;前…