目录

  • 初步思路
  • 朴素匹配算法
  • KMP算法
    • NEXT数组
    • 利用NEXT数组改进朴素匹配算法

初步思路

这是一道难度为简单的题,所以不熟悉的话可能第一反应就是朴素匹配的算法。但因为考研的时候学过数据结构,所以我第一反应是应该使用KMP算法,并私以为难度不应该归为简单,毕竟KMP算法代码虽然比较简单,但理解起来还是比较难。下图为LeetCode上的提交记录。

神奇的是在这个图片中,最上面的为朴素匹配算法,最下面为KMP算法。大家觉得更高级的算法竟然不如最直接暴力的算法????
LeetCode上的评分机制参考一下就行了,大家也不必深究,应该是它上面提供的评分算例比较简单,体现不出KMP算法的优势。中间一些解答错误,便是因为我觉得朴素匹配算法非常简单,没有认真调试,中间有个容易忽略的问题,后文我会提到。

朴素匹配算法

由于朴素算法便于理解,并可作为KMP算法的引子,所以先介绍这种算法。先直接上代码。

class Solution {public:    int strStr(string haystack, string needle) {if(needle.empty())return 0;int i=0;//源串int j=0;//子串int k=i;int len1=haystack.size();int len2=needle.size();while(i<len1&&j<len2) {if(haystack[i]==needle[j]) {i++;j++;} else {i=k++;//用k标识i起始位置j=0;}}if(j>=len2) {return i-j;}return -1;}
};

haystack为作为模版的源串,needle为待匹配的子串。实现逻辑就是从haystack的一个字符开始,与needle的第一个字符比较,如果相同则haystack的第二个字符与needle的第二个字符进行比较,若不同则haystack移动到haystack的第二个字符,重新开始与needle的第一个字符比较。如此循环下去,直到找到完全匹配的位置,或是haystack已经搜索完毕,但还没找到匹配的位置时结束。

但这种朴素匹配算法的时间复杂度为O(mn),因为中间可能有些比较可以跳过,但是它都得按顺序一一的比较过去(比如ABBBBBBABA中去找ABA)。而接下来介绍的KMP算法就可以减少无用的比较,直接跳到有效的位置。KMP算法的时间复杂度为O(m+n)。

需要注意的是:k用来标记当前源串i的起始位置,否则i遍历到后面会丢失其开始的位置。而j不需要被记录,因为若匹配失败,j都是从头开始。(提交失败的三次都是因为此原因被我忽略。)

KMP算法

KMP算法则是对上述算法的一个改进。它首先求出一个NEXT数组,其指明若发生匹配失败该跳到哪个位置开始重新进行匹配;然后利用NEXT数组对上述算法进行改进。上述算法需要按顺序一个一个往后匹配,而KMP利用NEXT数组直接跳到有效的位置。

NEXT数组

vector<int> getnext(string str){int len=str.size();vector<int> next;next.push_back(-1);//next数组初值为-1int j=0,k=-1;while(j<len-1){if(k==-1||str[j]==str[k])//str[j]后缀 str[k]前缀{j++;k++;next.push_back(k);}else{k=next[k];}}return next;}

NEXT数组的求解目的主要就是求子串中前缀码和后缀码最大的重合情况。(如ABBAB,ABBBA。)

【KMP算法易懂版-天勤率辉2020全程班公开一期讲解】指路该视频,简单易懂地介绍了NEXT数组的手动求解方法。

在理解了手动求法后,求NEXT数组的代码就很好理解了。
NEXT数组都是从前往后进行,所以求得next[i]后next[i+1]的求值可以分两种情况讨论:

  1. 若pi等于pj,则next[i+1]=j+1;因为j为当前最长的前后缀码重合情况,若pi等于pj,则相当于在当前的情况下加1。
  2. 若pi不等于pj,只需将j赋值为next[j],再对pi和pj进行比较。

利用NEXT数组改进朴素匹配算法

得到NEXT数组后,对朴素匹配算法中按顺序依次后挪改为根据NEXT数组寻找下一个位置即可。

int strStr(string haystack, string needle) {if(needle.empty())return 0;int i=0;//源串int j=0;//子串int len1=haystack.size();int len2=needle.size();vector<int> next;next=getnext(needle);while((i<len1)&&(j<len2)){if((j==-1)||(haystack[i]==needle[j])){i++;j++;}else{j=next[j];//获取下一次匹配的位置}}if(j==len2)return i-j;return -1;}

LeetCode第28题 实现strStr()之KMP算法(C++)【代码已提交成功】相关推荐

  1. LeetCode集锦(十) - 第28题 Implement StrStr

    LeetCode集锦(十) - 第28题 Implement StrStr 问题 Implement strStr().Return the index of the first occurrence ...

  2. 【To Do】LeetCode 28. Implement strStr() 和KMP算法

    LeetCode 28. Implement strStr() Solution1:我的答案 有投机取巧之嫌啊~ 注意string中的查找函数在查找时 参考网址:https://www.cnblogs ...

  3. 字符串匹配(KMP 算法 含代码)

    主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...

  4. strstr函数_leetcode第28题实现strStr()

    点击关注,我们共同每天进步一点点! 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个 ...

  5. 力扣28. 实现 strStr()(KMP算法,JavaScript)

    var strStr = function(haystack, needle) {//如果目标字符串长度为0,则返回0if(needle.length===0){return 0}//目标字符串长度不 ...

  6. 四 . LeetCode标签刷题——树/二叉树(一) 算法部分

    各种二叉树的介绍汇总: 二叉树:最多有两棵子树的树被称为二叉树 满二叉树:二叉树中所有非叶子结点的度都是2,且叶子结点都在同一层次上 完全二叉树:如果一个二叉树与满二叉树前m个节点的结构相同,这样的二 ...

  7. 看了这篇 LeetCode 的刷题心得,再也不用抄别人代码了

    作者:VioletJack 原文:<LeetCode 算法题刷题心得>https://www.jianshu.com/p/8876704ea9c8 花了十几天,把<算法>看了一 ...

  8. 【数据结构与算法】LeetCode面试真题,带你领略算法思想

  9. LeetCode部分刷题笔记!!!JavaScript!!!

    详细解说请看视频JS老毕:人人都能看得懂的Leetcode力扣刷题教程合集 边看视频边记录笔记!!!部分题目在视频中无! 文章目录 LeetCode第1题:1. 两数之和 LeetCode第2题:2. ...

最新文章

  1. 读大叔深入理解javascript(2)
  2. C++ Primer Plus 笔记第十章
  3. TDSQL 全时态数据库系统 -- 典型案例
  4. 模板模式(部分方法延迟到子类实现)
  5. linux 进程监控命令2——ps
  6. c语言基于easyX樱花特效,C++基于easyx图形库实现推箱子游戏
  7. ASP.NET中插入Flash
  8. 参考文献如何居中_一线教师如何写教育教学论文?
  9. 畅通工程(kruskal算法)
  10. IOS技术分享| WebRTC iOS源码下载编译
  11. wegame显示密保服务器,wegame英雄联盟设置 | 手游网游页游攻略大全
  12. 超声波测距模块工作原理
  13. 绵阳python培训_绵的繁体字怎么写_绵字有几笔、五行属性-幸运吧起名网
  14. python ERROR: Could not find a version that satisfies the requirement requests (from versions: none)
  15. cdr文件过大导出pdf打不开_cdr导出pdf 文件有问题怎么办
  16. 【20190405】算法-输入一个字符串,按字典序打印出该字符串中字符的所有排列
  17. 使用.net core ABP和Angular模板构建博客管理系统(实现博客列表页面)
  18. HTML 制作简单的导航栏
  19. 华为p20nfc怎么复制门禁卡_EMUI的这个功能,让手机瞬间化身门禁卡
  20. 软件及互联网高端灵活用工与技术服务提供商

热门文章

  1. SNMP Trap (V1,V2, V3)总结
  2. 如何在Salesforce Lightning组件中创建模态/弹出框
  3. Java SQLSyntaxErrorException: Key column ‘xxx‘ doesn‘t exist in table问题解决
  4. 一个BI项目是如何开展的
  5. 常用金属材料 钢管材料
  6. 华为机试题61-放苹果
  7. Chart.js 堆叠柱状图点击更换背景色以及加虚线边框
  8. Android逆向入门1——引言与抓包
  9. c语言利用指针函数等完成学生成绩管理系统,课程设计C语言可视化程序学生成绩管理系统...
  10. java毕业设计成品源码网站基于JSP的网上订餐管理系统|餐饮就餐订餐餐厅