题目描述:

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

示例 1:

输入:haystack = "sadbutsad", needle = "sad"

输出:0

解释:"sad" 在下标 0 和 6 处匹配。

第一个匹配项的下标是 0 ,所以返回 0 。

思路分析:

在进入主要流程之前应该进行非法行为断定:

  • 因为在题目中已经表示了两个字符串不会为空,所以不需要判断是否为空的情况
  • 如果模式串比目标串要长,则不可能有符合条件的下标,于是这种情况非法,其余情况正常继续。

找一个模式串在目标串中的起始位置,典型的KMP算法。有两种实现方法:暴力循环和KMP方法。他们的区别在于暴力法的复杂度是O(n^2)和O(m+n)。

暴力循环法:

就是依次从目标串的第一个位置不断开始找,如果达到模式串的长度时的字符串仍然相同,那就说明查找成功。否则从下一个开始的位置进行查找,具体实现如下,重点关注一下两个循环的指针的设计方案。用模式串的长度进行指针挪动可以减少一次循环。

点击查看代码
func strStr(haystack string, needle string) int {
if len(needle) == 0 {
return 0
}
var i, j int
// i不需要到len-1
for i = 0; i < len(haystack)-len(needle)+1; i++ {
for j = 0; j < len(needle); j++ {
if haystack[i+j] != needle[j] {
break
}
}
// 判断字符串长度是否相等
if len(needle) == j {
return i
}
}
return -1
}

KMP算法

前缀: 包含第一个字符的子串

KMP算法的核心就是利用之前的匹配过程的信息(最长公共前缀。因为他在匹配的过程中记录最长公共子串的长度,他相当于是对称的===:前面几个长度的字符和后面几个字符的长度是相同的,并且如果next数组(记录当前公共子串的长度)的值不为0,就说明到目前为止模式串和目标串的元素是有相同的的存在的。

即有三种情况:

p []int //寻找LPS的string

next []int //存储LPS的数组

length int //当前最长的LPS长度

  • 当前字符串相同的,匹配成功。length++,向后移动
  • 匹配失败:当前字符和之前的字符也没有能够组成的LPS,这里需要递归寻找,具体操作方法为:

    else if length!=0 {

    //只有这个判断条件没有发生i++,即找到相同的为止,要么重新找。这就是递归的体现。

    length = lps[length-1]

    给一个具体的例子:(来自知乎@凉拌炒鸡蛋)



    当找到下标13的c的时候,发生不匹配现象,但是之前串的length = 5,如果从头开始匹配复杂度就又上去了,所以依然要利用之前的匹配信息,将length-1直到为0看是否匹配。length-1的效果:其实就是不断缩短前缀的长度,看到最新不匹配的位置是否能通过减少字符的方法匹配上,他减少2个字符就匹配上了。
  • 实在不匹配就置为0,向后继续匹配。

代码:

点击查看代码
func computeLPSArray(pat string) []int {
lps:=make([]int,len(pat))
length:= 0
//从位置1开始遍历,找最长前缀长度
for i := 1; i < len(pat);{
if pat[i]==pat[length] {
length++
lps[i] = length
i++
}else if length!=0 {
//只有这个判断条件没有发生i++,即找到相同的为止,要么重新找。这就是递归的体现。
length = lps[length-1]
}else {
lps[i] = 0
i++
}
}
return lps
}

28. 找出字符串中第一个匹配项的下标 Golang实现的更多相关文章

  1. 剑指Offer 找出字符串中第一个只出现一次的字符

    题目描述 找出字符串中第一个只出现一次的字符 如果无此字符 请输出'.' 输入描述: 输入一串字符,由小写字母组成 输出描述: 输出一个字符 输入例子: asdfasdfo 输出例子: o 思路:数组 ...

  2. 找出字符串中第一个不重复的字符(JavaScript实现)

    如题~ 此算法仅供参考,小菜基本不懂高深的算法,只能用最朴实的思想去表达. //找出字符串中第一个不重复的字符 // firstUniqueChar("vdctdvc"); --& ...

  3. C++版 - 剑指Offer 面试题35:第一个只出现一次的字符 解题报告(华为OJ034-找出字符串中第一个只出现一次的字符)

    面试题35:第一个只出现一次的字符 题目:在一个字符串中找到第一个只出现一次的字符.如输入abaccdeff,则输出b.(2006年google的一道笔试题.) 分析: 首先应向确认一下是ASCII字 ...

  4. [LeetCode] Find All Anagrams in a String 找出字符串中所有的变位词

    Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. Strings ...

  5. 【easy】438.Find All Anagrams in a String 找出字符串中所有的变位词

    Input: s: "abab" p: "ab" Output: [0, 1, 2] Explanation: The substring with start ...

  6. js常会问的问题:找出字符串中出现次数最多的字符。

    一.循环obj let testStr = 'asdasddsfdsfadsfdghdadsdfdgdasd'; function getMax(str) { let obj = {}; for(le ...

  7. 【SQLSERVER】如何找出字符串中的数字

    可以通过写自定义函数实现,以下提供两种思路来解决: 1.通过正则匹配,找到字符串中的数字,一个一个拼起来 /*方法一: 一个一个找出来*/ CREATE FUNCTION [dbo].[Fun_Get ...

  8. [LeetCode] 438. Find All Anagrams in a String 找出字符串中所有的变位词

    Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. Strings ...

  9. C/C+面试题一:找出字符串中出现最多的字符和次数,时间复杂度小于O(n^2)

    已知字符串"aabbbcddddeeffffghijklmnopqrst"编程找出出现最多的字符和次数,要求时间复杂度小于O(n^2) /********************* ...

  10. python 找出字符串中出现次数最多的字母

    # 请大家找出s=”aabbccddxxxxffff”中 出现次数最多的字母 # 第一种方法,字典方式: s="aabbccddxxxxffff" count ={} for i ...

随机推荐

  1. 13、SpringMVC之异常解析器

    13.1.环境搭建 创建名为spring_mvc_exception的新module,过程参考9.1节和9.5节 13.1.1.创建错误提示页 <!DOCTYPE html> <ht ...

  2. 【RabbitMQ】04 路由模式

    在订阅模式的基础上制定一些特定发送规则 创建路由模式的生产者: 注意这些变化,跟之前的订阅模式并不一样 package cn.dzz.routineQueueInProducer; import co ...

  3. 【JavaScript】无框架翻页处理

    这个业务太复杂了 输入框的东西要用接口查出来,居然不是用户手动输入 然后我就要做一个翻页的查询列表: <div form id="troublePartSearch" sty ...

  4. 【Uni-APP】02 FLEX 弹性布局

    新建一个项目: 注释所有内容: <template> <!-- <view class="content"> <image class=&quo ...

  5. Jax框架的性能分析——性能分析可视化

    官方文档: https://jax.readthedocs.io/en/latest/profiling.html 将jax代码的性能文件写入到文件夹中,并给出上传第三方网站的链接生成(https:/ ...

  6. 成为Apache SeaTunnel贡献者的N种方式

    如何参与开源贡献 参与开源贡献的常见方法有多种: 1)参与解答 在社区中, 帮助使用过程中遇到困难的人,帮他们解释框架的用法也算是一种贡献. 2)文档贡献 帮助框架来完善文档,比如说将英文文档翻译为中 ...

  7. Vue-购物车实战

    computed 计算属性 正则 css部分 [v-cloak] { display : none ; } table{ border : lpx solid #e9e9e9 ; border- co ...

  8. 使用Typora编写后的md文件优雅的上传到博客(插件dotnet-cnblog的使用)

    一.Typora的设置 如下图,设置图片上传位置 之后文章上的图片都会临时存放到文件同级目录下的xxx.Asster文件夹下面. 二.下载插件dotnet-cnblog 1.安装.Net Core S ...

  9. Namomo Summer Camp 23 Day 1(GCPC2021)

    Namomo Summer Camp 23 Day 1(GCPC2021) Problem B: Brexiting and Brentering 签到 #include<bits/stdc++ ...

  10. 2021 CCPC 哈尔滨

    gym 开场 zsy 签了 J,gjk 签了 B,我读错了 E 的题意,gjk 读对后过了 zsy 读了 K 给我,我记得是模拟赛原题,跟欧拉定理有关,但很难.他俩过了 D I,我大概会了 G 但不会 ...