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

从零开始的LeetCode刷题日记:28. 实现 strStr()

一.相关链接

题目链接:28. 实现 strStr()

二.心得体会

1)KMP算法的思想

需要在一个字符串里找另一个字符串就需要用到KMP算法。KMP算法的重点是求出next数组,然后每次遇到不匹配的情况就根据数组来回退并重新匹配。

KMP算法的思想是最长相等前后缀,也就是省去再匹配前面子串的时间。

2)求next数组的流程

KMP算法求next数组的基本流程是:初始化,处理前后缀不匹配情况,处理前后缀匹配情况。

  1. 初始化:i设置为后缀末尾,j设置为前缀末尾(同时也代表了j前方的子串已经匹配成功),next[0]=0(第一个字母没有前后缀)。
  2. 处理前后缀不匹配的情况:如果不匹配,我们就需要一直向前回退,根据next[j-1]来一直回退到字符串头或者匹配为止(只有匹配了才说明存在某个前后缀长度相等且相同),本质就是不断缩小前后缀的长度以求找到匹配的最长相等前后缀。
  3. 处理前后缀匹配的情况:如果匹配,我们就可以j++,然后赋值next[i]=j,说明最长相等前后缀延长一位!
3)问题与思考

1. j的大小和所指字符的含义是什么?

答:j的大小指的是上一个子串已经成功匹配的最长前后缀长度。j所指字符是新加入子串的字符,代表当前需要进行匹配的后缀末尾。

2. 为什么是根据next[j-1]进行回退?

答:第一个解释是根据不变量原则,本质上求next数组也是一个小的查找子串的问题,因此和整个KMP所解决的问题是一致的,和KMP的流程是一样的。第二个解释是回退的本质是不断缩小前后缀长度的一个不断妥协的过程,这个过程我们可以逐个逐个向前回退来比较,但next数组记录了能够匹配的前缀位置,那么只需要让i所指字符和这些匹配了的前缀末尾来比较就可以确定next[i]了。

三.代码

1)实现KMP:

class Solution {
public:void getNextarray(int* next,string needle){//初始化int j=0;next[0]=0;//创建next数组for(int i=1;i<needle.size();i++){//处理前后缀不匹配情况while(j>0&&needle[i]!=needle[j]){j = next[j-1];}//处理前后缀匹配情况if(needle[i] == needle[j]){j++;}//赋值next[i] = j;}}int strStr(string haystack, string needle) {const int len = needle.size();int next[needle.size()];getNextarray(next,needle);int j=0;//进行KMP搜索for(int i=0;i<haystack.size();i++){//不匹配就根据next数组回退while(j>0&&haystack[i]!=needle[j]){j = next[j-1];}if(haystack[i]==needle[j]){j++;}if(j==needle.size()){//匹配完成后i指向neddle末尾,因此需要复位到开头return (i-needle.size()+1);}}return -1;}
};

2)库函数:

class Solution {
public:int strStr(string haystack, string needle) {auto result = search(haystack.begin(), haystack.end(), needle.begin(), needle.end());if (result != haystack.end())return (result - haystack.begin());else return -1;}
};

相关文章:

  • 【Java】Java使用Swing实现一个模拟计算器(有源码)
  • 入门用Hive构建数据仓库
  • 如何理解JVM
  • HTTP 摘要认证
  • vue3新手笔记
  • 【Java8新特性】四、强大的Stream api
  • 金陵科技学院软件工程学院软件工程专业
  • 韩顺平 | 零基础快速学Python(2)
  • 【.Net】Polly
  • Python 中全局变量缓存的多线程问题及优化策略
  • FPGA开源项目分享——基于 DE1-SOC 的 String Art 实现
  • 广佛站点导航助手小程序产品使用说明书
  • iOS 17.5系统或可识别并禁用未知跟踪器,苹果Find My技术应用越来越合理
  • 提升Terraform工作流程最佳实践
  • 五一假期来临,各地景区云旅游、慢直播方案设计与平台搭建
  • SegmentFault for Android 3.0 发布
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【RocksDB】TransactionDB源码分析
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • ECS应用管理最佳实践
  • IDEA常用插件整理
  • java小心机(3)| 浅析finalize()
  • LeetCode18.四数之和 JavaScript
  • MySQL-事务管理(基础)
  • PHP面试之三:MySQL数据库
  • 分享几个不错的工具
  • 构建二叉树进行数值数组的去重及优化
  • 解决iview多表头动态更改列元素发生的错误
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 前端代码风格自动化系列(二)之Commitlint
  • 少走弯路,给Java 1~5 年程序员的建议
  • 用mpvue开发微信小程序
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​决定德拉瓦州地区版图的关键历史事件
  • (8)STL算法之替换
  • (poj1.2.1)1970(筛选法模拟)
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (补)B+树一些思想
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • .CSS-hover 的解释
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .NET delegate 委托 、 Event 事件,接口回调
  • .NET 中 GetProcess 相关方法的性能
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .NET和.COM和.CN域名区别
  • .sh
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • @kafkalistener消费不到消息_消息队列对战之RabbitMq 大战 kafka
  • [CSS]中子元素在父元素中居中
  • [C语言]编译和链接
  • [E单调栈] lc2487. 从链表中移除节点(单调栈+递归+反转链表+多思路)
  • [GDMEC-无人机遥感研究小组]无人机遥感小组-000-数据集制备
  • [hdu1561] The more, The Better 【树形DP】