LeetCode 28. 实现 strStr()

leetcode 028.实现strStr(),即查找重复字符串(KMP算法) 前言 本题是经典的字符串单模匹配的模型,因此可以使用字符串匹配算法解决,常见的字符串匹配算法包括暴力匹配、Knuth-Morris-Pratt 算法、Boyer-Moore 算法、Sunday 算法等,本文 ## 前言 本题是经典的字符串单模匹配的模型,因此可以使用字符串匹配算法解决,常见的字符串匹配算法包括暴力匹配、Knuth-Morris-Pratt 算法、Boyer-Moore 算法、Sunday 算法等,本文将讲解朴素解法(暴力匹配)和KMP算法 因为哈希方法可能出现哈希值相等但是字符串不相等的情况 阅读详情

链接:https://leetcode-cn.com/problems/implement-strstr/

题目描述:

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

示例 1:

输入:haystack = "hello", needle = "ll"
输出:2
示例 2:

输入:haystack = "aaaaa", needle = "bba"
输出:-1
示例 3:

输入:haystack = "", needle = ""
输出:0

虽然这是一道简单题,但是也有着不简单的解法,这里附上暴力匹配的解法和Rabin Karp的解法,至于KMP的解法虽然经典,但是代码并不好记,实际面试还是采用Rabin Karp更加方便,而且两者时间复杂度相同。

1 暴力匹配

原字符串长度为n,需匹配字符串长度为m。时间复杂度 O(m*n)

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if haystack is None or needle is None:
            return -1
        if len(needle) == 0:
            return 0

        tar_len = len(needle)
        for i in range(len(haystack) - tar_len + 1):
            for j in range(tar_len):  # 原地匹配, 避免传参过程中复制字符串的时间消耗
                if haystack[i + j] != needle[j]:
                    break
            else:
                return i
        return -1

2 Rabin Karp

时间复杂度 O(n+m)
Rabin Karp解法的思路十分好记,将原来暴力解法中每个子串的匹配,代替成哈希值的匹配即可,不过哈希值的计算需要仔细设计,通过前一个子串的哈希值,就可以在O(1)的时间下算出下一个子串的哈希值,因此匹配哈希值的部分需要O(n)。最后在哈希值相等的情况下,为了避免哈希冲突,再次进行字符的逐个匹配,时间消耗O(m) ,所以最终时间复杂度为O(n+m)

class Solution_Rabin_Karp:
    """
    Rabin Karp 算法求解字符串匹配 时间O(n+m)
    """
    def strStr(self, haystack: str, needle: str) -> int:
        if haystack is None or needle is None:
            return -1
        if len(needle) == 0:
            return 0

        tar_len = len(needle)
        tar_hash = self.str2hash(needle, begin=0, end=tar_len, order=0)
        src_hash = 0
        for i in range(len(haystack) - tar_len + 1):
            src_hash = self.str2hash(haystack, begin=i, end=i + tar_len, pre_hash=src_hash, order=i)
            if src_hash == tar_hash:
                for j in range(tar_len):
                    if haystack[i + j] != needle[j]:  # 再次比较, 避免哈希冲突的结果
                        break
                else:
                    return i
        return -1

    def str2hash(self, input_str, begin, end, pre_hash=0, order=0):

        hash_value = 0
        weight = 31
        mod = 1e6

        if order == 0:
            for s in input_str[begin:end]:
                hash_value = hash_value * weight + ord(s)
                hash_value = int(hash_value % mod)
            return hash_value

        power = pow(weight, end - begin - 1) % mod
        hash_value = pre_hash - ord(input_str[begin - 1]) * power
        hash_value = (hash_value + mod) % mod  # 防止为负数
        hash_value = hash_value * weight + ord(input_str[end - 1])

        return int(hash_value % mod)

3 原地匹配

由于字符串是不可变类型,在进行函数参数传递时将为形参重新生成一份原字符串,这里将进行一定时间的消耗。而在原地计算哈希值或匹配字符串,则可避免这些消耗,下面是Rabin Karp原地哈希的代码,多次运行计时后,发现是比传参的形式快了一些,但代码的可读性就差了一点。

class Solution_Rabin_Karp_inplace:
    """
    Rabin Karp 算法求解字符串匹配 时间O(n+m)
    """
    weight = 31
    Base = 1e6

    def strStr(self, haystack: str, needle: str) -> int:
        if haystack is None or needle is None:
            return -1
        if len(needle) == 0:
            return 0

        tar_len = len(needle)

        # generate target hash code
        tar_hash = 0
        for s in needle:
            tar_hash = tar_hash * self.weight + ord(s)
            tar_hash = int(tar_hash % self.Base)

        src_hash = 0
        for i in range(len(haystack) - tar_len + 1):
            if i == 0:  # first substring hash code
                for s in haystack[i: i + tar_len]:
                    src_hash = src_hash * self.weight + ord(s)
                    src_hash = int(src_hash % self.Base)
            else:
                power = pow(self.weight, tar_len - 1) % self.Base
                src_hash = src_hash - ord(haystack[i - 1]) * power
                src_hash = (src_hash + self.Base) % self.Base  # 防止为负数
                src_hash = int(src_hash * self.weight + ord(haystack[i + tar_len - 1])) % self.Base

            if src_hash == tar_hash:
                for j in range(tar_len):
                    if haystack[i + j] != needle[j]:  # 再次比较, 避免哈希冲突的结果
                        break
                else:
                    return i
        return -1
LeetCode28 KMP算法实例 LeetCode28题 KMP算法初见 阅读详情

相关推荐

LeetCode28—KMP算法

实现strStr() 1. 题目描述 实现 strStr() 函数。 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。 说明: 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。 示例 输入:

xws__meizhong的博客 344

28. 实现 strStr()

https://leetcode-cn.com/problems/implement-strstr/ 难度简单1002 实现strStr()函数。 给你两个字符串haystack和needle,请你在haystack字符串中找出needle字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回-1。 说明: 当needle是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 对于本题而言,当needle是空字符串时我们应当返回 0 。这与...

肥不溜秋大梅子 546

LeetCode——28,实现 strStr() 函数

/** * \* Created: liuhuichao * \* Date: 2019/4/23 * \* Time: 11:25 AM * \* Description: 实现 strStr() 函数 * <p> * 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如...

我们的征途是星辰大海 730

#每日一题#实现函数:给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)如果不存在,则返回 -1

我的前端面试题练习》》》#每日一题 问题描述: 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/implement-strstr 实现strStr() 函数。 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。 说明: 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 对于本题而言,当 n

老衲的少女心i~ 5175

微信H5网页授权通用方案:中转页破解域名限制,适配Hash/History路由

在Web开发中,OAuth 2.0授权码模式是实现第三方登录的通用标准,其核心原理是通过授权服务器颁发临时代码,再由客户端交换访问令牌。这一机制在微信公众号H5开发中尤为重要,用于安全获取用户身份。然而,微信平台对网页授权回调域名有严格的数量限制,这成为多子域名、多环境及微前端架构下业务扩展的主要瓶颈。其技术价值在于通过设计一个统一的中转授权页,将授权逻辑与业务逻辑解耦,让所有业务页面共享一个已配置的授权入口,从而突破域名配额限制。该方案的关键在于适配不同的前端路由模式,需精准处理Hash模式与Histor

weixin_42533120的博客 318

单细胞测序数据读取实战指南:从入门到精通

本文提供了单细胞测序数据读取的实战指南,涵盖从标准10X Genomics格式到通用表达矩阵及RDS文件的读取方法。文章重点解析了数据读取的核心步骤、常见问题解决方案及进阶技巧,旨在帮助用户夯实数据分析基础,确保后续分析流程的准确性。

weixin_29095587的博客 459

LeetCode力扣真题解惑第1篇 —— 力扣第28题:实现 strStr()函数

LeetCode力扣真题解惑第1篇 —— 实现 strStr() 28. 实现 strStr() 函数。 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。 示例 1: 输入: haystack = “hello”, needle = “ll” 输出: 2 示例 2: 输入: haystack = “aaaaa”, needle = “bba” 输出: -1 说明: 当 need

浮生若梦,云游四方 492

ARM双核锁步DCLS Lockstep技术研究(FPGA实现)

基于《Applying Dual-Core Lockstep in Embedded Processors to Mitigate Radiation-induced Soft Errors》文章总结 RISC-V双核锁步DCLS Lockstep技术参考之前文章: RISC-V双核锁步DCLS Lockstep技术总结_远古架构师alanwu的博客-优快云博客https://blog.csdn.net/heyuming20062007/article/details/123329537ARM+RIS

heyuming20062007的博客 8726

strstr函数c语言库函数_LeetCode力扣真题解惑第1篇 —— 力扣第28题:实现 strStr()函数...

LeetCode力扣真题解惑第1篇 —— 力扣第28题:实现 strStr()函数28. 实现 strStr() 函数。给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。示例 1:输入: haystack = “hello”, needle = “ll”输出: 2示例 2...

weixin_35823441的博客 207

基于自抗扰控制的虚拟同步发电机二次调频控制研究

摘要:本文针对高比例可再生能源并网导致的电力系统频率稳定性问题,提出基于自抗扰控制(ADRC)的虚拟同步发电机(VSG)二次调频控制策略。通过分析VSG工作原理和传统调频方法的不足,设计了非线性ADRC和线性ADRC两种控制器,详细阐述了参数整定方法。仿真结果表明,该策略能有效消除频率稳态偏差,提升系统抗扰能力,为分布式电源参与电网调频提供了新思路。 关键词:虚拟同步发电机;自抗扰控制;二次调频;频率调节;抗扰能力

huanghm88的专栏 243

C语言试题四之计算并输出3到n之间所有素数的平方根之和

1、题目 请编写函数function,它的功能是:计算并输出3到n之间所有素数的平方根之和 例子:若我们main函数从键盘给n输入5之后,我们需要输出结果为3.968119 输入值n的要求:正整数n, 要求小于100。 2、部分函数说明 C 库函数 double sqrt(double x) 返回 x 的平方根 3、源代码实现 #include <stdio.h> #...

码莎拉蒂 7232

【leetcode力扣】PHP实现:28. 实现 strStr()

题目: 实现strStr()函数。 给定一个haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回-1。 示例 1: 输入: haystack = "hello", needle = "ll" 输出: 2 示例 2: 输入: haystack = "aaaaa", n...

allen的博客 608

金砖大赛-第二届网络安全防护治理实战技能大赛全国总决赛WP

格式进行md4加密,然后将小写的md4密文进行作为flag信息进行提交,提交格式为flag{MD4小写},例如调用频率异常高的user_id是user_xxx,使用的非公开模型名称是model-name,具体调用次数为10,那么按照格式,对user_xxx:model-name:10进行md4加密后,提交范例为:flag{dd00cb9e393f4a9ac639294b3cfe4d6a}挖矿木马是通过远程脚本进行部署的,请登录到失陷的服务器上,找到并分析挖矿木马是从那个远程IP下载的。

Laffrey的专栏 238

LeetCode力扣 28. 实现 strStr() Implement strStr() 题解代码 JavaScript

问题https://leetcode-cn.com/problems/implement-strstr/ 练习使用JavaScript解答 /** * @param {string} haystack * @param {string} needle * @return {number} */ var strStr = function(haystack, needle) { return haystack.indexOf(needle); }; 题目是让实现,直接用库好像不太合适.

Coding home - 漂流瓶jz 512

YOLOv11改进策略【注意力机制篇】| SE、CBAM、ECA、CA、Swin Transformer等注意力机制全面解析与应用

本文详细介绍了五种主流的注意力机制及其在YOLOv11中的应用。通过合理的模块选择和位置部署,注意力机制能够显著提升目标检测性能。

QQ_778132974的博客 873

化工管道设计软件:CAESAR II二次开发_(6).API接口与函数库

自定义函数库是开发者根据特定需求编写的函数集合。这些函数可以扩展CAESAR II的功能,实现更复杂的管道设计任务。自定义函数库通常需要开发者具备一定的编程基础,能够理解和编写与CAESAR II接口兼容的代码。定义函数:在Python或其他编程语言中定义所需的函数。注册函数:将自定义函数注册到CAESAR II的函数库中。调用函数:在CAESAR II中调用自定义函数,实现特定功能。假设我们需要创建一个自定义函数库,用于批量修改管道节点的坐标。定义函数:在Python中定义一个函数,用于批量修改节点坐标。

kkchenjj的博客 1726

Leetcode 28. 实现strStr() Python

Leetcode 28. 实现strStr Python题目自己解法偷鸡解法 题目 实现 strStr() 函数。 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。 示例 1: 输入: haystack = “hello”, needle = “ll” 输出: 2 示...

yo跟着新宇走 349

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

力扣28实现strStr()

力扣28实现strStr() 概述 这道题是要在 haystack 字符串中找到 needle 字符串。下面会给出的三种解法,这三种解法都基于滑动窗口。 子串逐一比较的解法最简单,将长度为 L 的滑动窗口沿着 haystack 字符串逐步移动,并将窗口内的子串与 needle 字符串相比较,时间复杂度为 O((N - L)L)O((N−L)L) 显示上面这个方法是可以优化的。双指针方法虽然也是线性时间复杂度,不过它可以避免比较所有的子串,因此最优情况下的时间复杂度为 O(N)O(N),但最坏情况下的时间复杂

qq_40310710的博客 129

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

LeetCode-28 实现strStr()

LeetCode-28 实现strStr() title: ‘LeetCode-28 实现strStr()’ date: 2018/6/29 16:39:20 tag: [LeetCode,双指针,字符串] categories: 面试题 实现 strStr() 函数。 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 need...

Jae_Peng的博客 403

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Leetcode 28. Implement strStr() 实现strStr()

Leetcode 28. Implement strStr() 实现strStr() 标签: Leetcode 题目地址:https://leetcode-cn.com/problems/implement-strstr/ 题目描述 实现&nbsp;strStr()&nbsp;函数。 给定一个&nbsp;haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 n...

CoderWangSon 163

LeetCode 28 实现 strStr()

LeetCode 28 实现 strStr() 题目 实现 strStr() 函数。 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。 示例 1: 输入: haystack = “hello”, needle = “ll” 输出: 2 示例 2: 输入: haysta...

Ailecccc的博客 119

LeetCode 28 实现strStr()

LeetCode 28 strStr() 1. 题解: 实现 strStr() 函数 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。 说明: 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

qq_51451731的博客 202

LeetCode-[28] 实现strStr()

@lc app=leetcode.cn id=28 lang=java [28] 实现strStr() https://leetcode-cn.com/problems/implement-strstr/description/ algorithms Easy (38.00%) Total Accepted: 48K Total Submissions: 126.2K Testcas...

fffzlfk的博客 169

leetCode_28. 实现 strStr()

leetcode_28. 实现 strStr() 一、题目描述 实现 strStr() 函数。 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。 说明: 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf()

qq_47346664的博客 354
上一篇: LeetCode 5. 最长回文子串
下一篇: 深度可分离卷积 (Depth-wise Separabel Convolution)
von Libniz
博客等级 码龄8年 421粉丝 173原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值