代码随想录刷题-字符串-实现 strStr()
文章目录
- 实现 strStr()
- 习题
- 暴力解法
- kmp 解法
实现 strStr()
本节对应代码随想录中:代码随想录,讲解视频:帮你把KMP算法学个通透!(理论篇)_哔哩哔哩_bilibili、帮你把KMP算法学个通透!(求next数组代码篇)_哔哩哔哩_bilibili
习题
题目链接:28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
示例 1:
输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。
暴力解法
题目意思是 needle 字符串是否在 haystack 字符串中出现,如果出现返回第一次出现的位置
那么直观的解法就是遍历 haystack 字符串,不断地将当前字符串与 needle 第一个字符比较,如果相同,则再依次比较后续长度的元素是否还是等于 needle 对应位置的元素。需要注意的是遍历 haystack 字符串的边界条件是 i+needle.size()<=haystack.size(),因为一旦剩余的 haystack 字符串小于 needle 的长度,那肯定无法匹配,避免 haystack[i+j] 可能出现数组越界的情况
class Solution {
public:int strStr(string haystack, string needle) {int n = haystack.size(), m = needle.size();// 循环遍历haystack,i表示当前检查的位置for (int i = 0; i + m <= n; i++) {bool flag = true;// 循环遍历needle字符串的每个字符for (int j = 0; j < m; j++) {if (haystack[i + j] != needle[j]) { // 如果在某个字符处匹配失败,则标记flag为false,跳出循环flag = false;break; } }if (flag) { // 如果整个needle字符串都匹配上了,返回起始位置ireturn i;}}return -1;// 如果找不到needle字符串,返回-1}
};
- 时间复杂度:O(m∗nm*nm∗n)。通过两层循环实现字符串匹配,外层循环的次数是 n - m + 1(其中n是haystack的长度,m是needle的长度),内层循环的次数是needle的长度m。因此,该算法的时间复杂度为 O(nm)
- 空间复杂度:O(111)。用了常量级别的额外存储空间,因为只使用了几个整型变量和两个字符串形参,不随着输入数据量的变化而变化。因此,该算法的空间复杂度为 O(1)
kmp 解法
这道题主要还是考察 kmp。上面的暴力解法,一旦不匹配我们是向后移动一位再尝试匹配,而 kmp 则优化了这个移动的过程,向后移动更多位来提高效率。简单来讲,如下图,kmp 是将公共前后缀的前缀移到了后缀的位置而不是像①一样只移动一位位置。
关于 kmp 的理论,建议先看这个视频:【天勤考研】KMP算法易懂版_哔哩哔哩_bilibili,了解下原理。再去看代码随想录的视频熟悉代码该怎么写。

那么每次不匹配的时候该移动多少呢,这就涉及到 next 数组的构建。在进行字符串匹配的时候,我们先构建 next 数组用来记录每个位置的公共前后缀长度,之后当不匹配的时候直接根据 next 数组进行移动。
class Solution {
public:// 获取next数组,用于字符串匹配void getNext(int* next, const string& s) {// ①初始化next数组第一个值为0int j = 0;next[0] = 0; // 循环遍历s中每个字符for(int i = 1; i < s.size(); i++) { // ②前后缀不相同while (j > 0 && s[i] != s[j]) {j = next[j - 1]; //若匹配失败则回溯到之前的状态继续匹配}// ③前后缀相同if (s[i] == s[j]) { //若当前字符和目标匹配j++; //将匹配数量+1}// ④更新next数组next[i] = j; //将新的匹配数量重新赋值至next数组}}// 实现字符串匹配算法int strStr(string haystack, string needle) {int next[needle.size()];getNext(next, needle); //获取needle字符串的next数组int j = 0; //j代表子串needle中已经匹配到的字符个数// 循环遍历haystack中的每个字符for (int i = 0; i < haystack.size(); i++) { while(j > 0 && haystack[i] != needle[j]) {j = next[j - 1]; //回溯,将j移动到目前匹配的最长公共前后缀的结尾处}if (haystack[i] == needle[j]) { //如果当前字符匹配成功j++; //继续匹配下一个字符}if (j == needle.size() ) { //如果匹配成功,返回子串在字符串中的位置return (i - needle.size() + 1);}}return -1; //匹配失败,返回-1}
};
- 时间复杂度:O(m+nm+nm+n)。其中 m 和 n 分别为 haystack 和 needle 字符串的长度。在 strStr 函数中,有一个 while 循环嵌套在 for 循环中,循环次数最多为 haystack 字符串长度 m 加上 needle 字符串长度 n,所以时间复杂度为 O(m+n)
- 空间复杂度:O(nnn)。定义了一个 int 数组 next,其长度为 needle 字符串长度 n,所以空间复杂度为 O(n)
相关文章:
代码随想录刷题-字符串-实现 strStr()
文章目录实现 strStr()习题暴力解法kmp 解法实现 strStr() 本节对应代码随想录中:代码随想录,讲解视频:帮你把KMP算法学个通透!(理论篇)_哔哩哔哩_bilibili、帮你把KMP算法学个通透!࿰…...
前端已死?金三银四?你收到offer了吗?
目录 一、前言 二、“唱衰” 三、不局限于框架、前端 四、打动面试官 五、正向加成 六、小结 一、前言 最近在脉脉、知乎等平台都有人在渲染前端从业人员的危机,甚至使用“前端已死”的字眼,颇有“语不惊人死不休”的意味,对老鸟来说&a…...
C生万物 | 十分钟带你学会位段相关知识
结构体相关知识可以先看看这篇文章 —— 链接 一、什么是位段 位段的声明和结构是类似的,有两个不同: 位段的成员必须是 int、unsigned int 或signed int位段的成员名后边有一个冒号和一个数字 在下面,我分别写了一个结构体和一个位段&…...
Spring Boot基础学习之(十):修改员工的信息
注意:spring boot专栏是一个新手项目,博文顺序则是功能实现的流程,如果有看不懂的内容可以到前面系列去了解。 本次项目所有能够使用的静态资源可以免费进行下载 静态资源 在本篇代码DAO层将通过Java文件去实现,在这里就不连接数…...
闭关十几天,我完成了我的毕业设计
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,也会涉及到服务端(Node.js) 📃个人状态: 在校大学生一枚,已拿多个前端 offer(…...
认识rust的项目管理工具--cargo
cargo 提供了一系列的工具,从项目的建立、构建到测试、运行直至部署,为 Rust 项目的管理提供尽可能完整的手段。不过,我们无需再手动安装,之前安装 Rust 的时候(用rustup或者vscode加插件的方式安装)&#…...
面试常问的Linux之 I/O 复用
I/O 复用 一、I/O的概念 在Linux系统中,I/O(输入/输出)指的是计算机系统的数据交换过程,包括从外部设备读取数据(输入)和将数据发送到外部设备(输出)。I/O操作是Linux系统中非常重要…...
MySQL-binlog+dump备份还原
目录 🍁binlog日志恢复 🍂binlog介绍 🍂Binlog的用途 🍂开启binary log功能 🍂配置binlog 🍁mysqldump 🍂数据库的导出 🍂数据库的导入 🍁mysqldumpbinlog 🦐…...
互联网络-单级互联网络
1.立方体单级网络 1.定义 立方体单级网络(cube)的名称来源于下图所示的三维立方体结构,如010只能连接到000、011、110,不能直接连接到对角线上的001、100、101、111。 2.例题 1.编号为0、1、2、3、4,…,15的16个处理器,用单级互联网络互联,用Cube0互联函数时,与第10…...
上海亚商投顾:沪指四连阳重回3300点 中字头个股再发力
上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 市场情绪大小指数今日走势分化,沪指低开后震荡反弹,创业板指盘中跌超1%。中字头个股再度发力&#x…...
LeetCode:150. 逆波兰表达式求值—栈
🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀算法专栏: 👉🏻123 一、🌱150. 逆波兰表达式求值 题目描述:给你一个字符串数组 token…...
C/C++每日一练(20230410) 二叉树专场(4)
目录 1. 二叉搜索树迭代器 🌟🌟🌟 2. 验证二叉搜索树 🌟🌟🌟 3. 不同的二叉搜索树 II 🌟🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专…...
策化整理1
概述: 本游戏是一款恐怖类解密游戏,以反应毒品的危害和反对家庭暴力为主题 在游戏中玩家扮演被困入梦境内的主人公,寻找逃出梦境的方法 本游戏故事大背景: 主人公的父亲是一名毒贩,在母亲发现父亲开始吸毒后选择与父亲…...
【服务通信自定义srv调用3----客户端的优化】
客户端的优化 服务通信自定义srv调用,客户端随意提交两个数,完成数的相加。也就是实现参数的动态提交: 1.格式:rosrun xxxx xxxx 12 34 2.节点执行时候,需要获取命令中的参数,并且组织进 request 代码中应…...
React跨域解决方案
一、跨域日志报错 我们由于项目需要经常会需要对不同域名、不同子域的网站接口发起请求,有时甚至是对于同一域名的不同端口发起请求,此时我们经常看到以下报错: Access to XMLHttpRequest at xxx from origin xxx has been blocked by COR…...
内存五区的概念,内存池技术的诞生。
首先提出一道经典的面试题来引出今天的主角: 进程的虚拟空间分布是什么样的,全局变量放在哪里? 在数据初始化之后,全局变量放在.data段 在数据未初始化时,全局变量放在.bss段 内存五区 进程虚拟内存主要分为五个部分…...
力扣:字符串中的第一个唯一字符(C++实现)
题目部分: 解题思路: 方案一: 首先认真审题的小伙伴们一定会发现就是题目给了提示只包含小写字母,也就是说我们的排查范围是小写的26个字母。为了怕有的友友们一时短路想不起来,我就其按照顺序列出来吧。 即&#x…...
攻防世界 favorite_number mfw、[BJDCTF2020]ZJCTF,不过如此
favorite_number 进入环境得到源码 <?php //php5.5.9 $stuff $_POST["stuff"]; $array [admin, user]; if($stuff $array && $stuff[0] ! admin) {$num $_POST["num"];if (preg_match("/^\d$/im",$num)){if (!preg_match("…...
SummingMergeTree
假设有这样⼀种查询需求:终端⽤户只需要查询数据的汇总结果,不关⼼明细数据,并且数据的汇总条件是预先明确的(GROUP BY 条件明确,且不会随意改变)。 对于这样的查询场景,在ClickHouse中如何解决…...
JUC并发编程基础篇第一章之进程/并发/异步的概念[理解基本概念]
1. 进程和线程的概念 进程: 系统正在运行的一个应用程序;程序一旦运行就是一个进程;进程是资源分配的最小单位 线程: 是进程的实际运行单位;一个人进程可以并发控制多个线程,每条线程并行执行不同的任务 区别: 进程基本上相互独立的;而线程存在于进程内,是进程…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
