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

一天一道算法题day07

找出字符中第一个匹配的下标

题目描述

给你两个字符串 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 。

解题思路 

暴力匹配算法。其基本思想是,从 haystack 中的每个字符位置开始,与 needle 字符串逐个进行比较,如果发现不匹配就继续移动 haystack,直到找到匹配项或搜索结束。

public int strStr(String haystack, String needle) {int m = haystack.length();int n = needle.length();if (n == 0) return 0; // 空字符串特殊处理for (int i = 0; i <= m - n; i++) {int j = 0;while (j < n && haystack.charAt(i + j) == needle.charAt(j)) {j++;}if (j == n) return i; // 匹配成功}return -1; // 未找到匹配项
}

这种方法的时间复杂度是 O(m * n),其中 m 是 haystack 的长度,n 是 needle 的长度。当 needle 很短而 haystack 很长时,这种方法的效率会变得低下。因此,为了提高效率,可以使用 KMP 算法。 

KMP 算法简介 

KMP(Knuth-Morris-Pratt)算法是一种高效的字符串匹配算法,它通过部分匹配表(又称为前缀表)来加快匹配过程,避免重复检查已经匹配过的字符。 

KMP 算法原理 

KMP 的核心思想是在匹配过程中,如果发现了不匹配字符,算法会利用之前已经匹配过的字符信息,移动 needle 字符串,而不是从头开始匹配。这是通过构建部分匹配表(前缀表)来实现的。

部分匹配表存储了每个位置之前的最长相同前后缀长度。例如: 对于 needle = "abcab",其部分匹配表为 [0, 0, 0, 1, 2]

  • 第一个字符 a 没有前后缀,因此为 0。
  • ab 没有相同的前后缀,因此为 0。
  • abc 也没有相同前后缀,为 0。
  • abca 的前缀 a 和后缀 a 匹配,为 1。
  • abcab 的前缀 ab 和后缀 ab 匹配,为 2。

KMP 算法步骤 

  • 构建部分匹配表(前缀表):根据 needle 构造出每个位置的最长相同前后缀长度。
  • 使用部分匹配表进行匹配:在主串中逐步匹配子串,当发生不匹配时,利用部分匹配表快速跳过不必要的比较。

KMP 算法实现 

public class Solution {public int strStr(String haystack, String needle) {if (needle.isEmpty()) return 0;int[] lps = computeLPSArray(needle);int i = 0, j = 0; // i 是 haystack 的索引,j 是 needle 的索引while (i < haystack.length()) {if (haystack.charAt(i) == needle.charAt(j)) {i++;j++;}if (j == needle.length()) {return i - j; // 找到匹配项,返回下标} else if (i < haystack.length() && haystack.charAt(i) != needle.charAt(j)) {if (j != 0) {j = lps[j - 1]; // 使用部分匹配表跳过重复比较} else {i++;}}}return -1; // 未找到匹配项}// 构造部分匹配表private int[] computeLPSArray(String needle) {int[] lps = new int[needle.length()];int length = 0;int i = 1;while (i < needle.length()) {if (needle.charAt(i) == needle.charAt(length)) {length++;lps[i] = length;i++;} else {if (length != 0) {length = lps[length - 1];} else {lps[i] = 0;i++;}}}return lps;}
}

复杂度分析

KMP 算法的时间复杂度为 O(m + n),其中 m 是 haystack 的长度,n 是 needle 的长度。相比于暴力匹配算法,KMP 通过部分匹配表有效减少了字符的重复比较,显著提升了效率。

 

 

 

相关文章:

一天一道算法题day07

找出字符中第一个匹配的下标 题目描述 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 示例 1&#…...

电机学习-有感BLDC开环控制(六步换相)

文章目录 1. 简介2. 六步换向控制3. 机械角度和电角度4.转子位置获取5.霍尔传感器读取测试6.速度开环控制6.1 PWM设置6.2死区时间 1. 简介 BLDC的反电动势一般是梯形的反电动势&#xff0c;所以采用方波控制。如图2-1所示&#xff0c;是一个简化的内转子无刷直流电机。我们通过…...

《深度学习》PyTorch框架 优化器、激活函数讲解

目录 一、深度学习核心框架的选择 1、TensorFlow 1&#xff09;概念 2&#xff09;优缺点 2、PyTorch 1&#xff09;概念 2&#xff09;优缺点 3、Keras 1&#xff09;概念 2&#xff09;优缺点 4、Caffe 1&#xff09;概念 2&#xff09;优缺点 二、pytorch安装 1、安装 2、…...

Linux:进程(四)

目录 一、进程优先级 二、Linux调度与切换 1.背景 2.进程切换 一、进程优先级 背景&#xff1a;在计算机中&#xff0c;软硬件资源是有限的&#xff0c;而进程想要访问某一种资源&#xff0c;就得通过排队来保证访问资源的过程是有条不紊的。 Linux下对优先级的定义。执行命…...

CTC loss 博客转载

论文地址&#xff1a; https://www.cs.toronto.edu/~graves/icml_2006.pdf 为了对应这个图&#xff0c;我们假设一种符合的模型情况&#xff1a; 英文OCR&#xff0c;37个类别&#xff08;26个小写字母10个汉字空格&#xff09;&#xff0c;最大输出长度8个字符 模型预测结果…...

TryHackMe 第3天 | Pre Security (中)

该学习路径讲解了网络安全入门的必备技术知识&#xff0c;比如计算机网络、网络协议、Linux命令、Windows设置等内容。上一篇中简短介绍了计算机网络相关的知识&#xff0c;本篇博客将记录 网络协议 部分。 How the web works? DNS in detail DNS (Domain name system&…...

c语言中“qsort函数”和“结构体成员访问变量”

qsort函数&#xff1a; qsort是c语言中的库函数&#xff0c;这个函数是对数据进行排序&#xff08;对任意&#xff09; 冒泡排序中排列整数顺序用的函数只适用于整形&#xff0c;而qsort函数适用与所有数据 排序算法 冒泡排序 插入 选择 快速 void qsort{ void * base&…...

【MySQL】在MySQL中STR_TO_DATE()

1.在MySQL中STR_TO_DATE() 在MySQL中&#xff0c;STR_TO_DATE() 函数用于将字符串转换为日期格式。这个函数非常有用&#xff0c;当你需要将文本数据转换为可由MySQL日期和时间函数处理的格式时。 1.1 语法 STR_TO_DATE() 函数的基本语法如下&#xff1a; STR_TO_DATE(date…...

PCIE集成验证(五)MSI/MSI-X中断

PCI 总线最早采用的中断机制是 INTx&#xff0c;这是基于边带信号的。后续的 PCI/PCI-X版本&#xff0c;为了消除边带信号&#xff0c;降低系统的硬件设计复杂度&#xff0c;逐渐采用了 MSI(Message Signaled Interrupt)/MSI-X&#xff08;消息信号中断&#xff09;的中断机制。…...

leetcode 380.O(1) 时间插入、删除和获取随机元素

实现RandomizedSet 类&#xff1a; RandomizedSet() 初始化 RandomizedSet 对象bool insert(int val) 当元素 val 不存在时&#xff0c;向集合中插入该项&#xff0c;并返回 true &#xff1b;否则&#xff0c;返回 false 。bool remove(int val) 当元素 val 存在时&#xff0…...

基于MicroPython的ESP8266控制PS2摇杆模块的设计方案

以下是一个基于MicroPython的ESP8266控制PS2摇杆模块的设计方案&#xff1a; 一、硬件准备&#xff1a; 1. 一块ESP8266开发板&#xff0c;如NodeMCU 2. 一个带有X、Y轴模拟输出和Z轴(按钮)数字输出的PS2摇杆模块 3. 杜邦线若干 4. 3.3V直流电源 二、硬件连接&#xff1a…...

Spring Boot 3项目使用Swagger3教程

Spring Boot 3项目使用Swagger3教程 Swagger&#xff1a;自动生成接口文档 添加依赖(pom.xml) <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.1…...

linux-系统备份与恢复-系统恢复

Linux 系统备份与恢复&#xff1a;系统恢复 1. 概述 Linux 系统的恢复是系统管理的重要组成部分&#xff0c;它指的是在系统崩溃、硬件故障、误操作或安全问题后&#xff0c;恢复系统到可用状态的过程。良好的系统恢复计划可以有效避免数据丢失和业务中断&#xff0c;并确保系…...

【Rust语言】std::collections::HashMap用法

HashMap用法文档 文章目录 创建键的要求 增删改查增: insert删: remove/remove_entry改单点修改 get_mut整体修改 values_mut/iter_mut 查集增改于一身的entry 遍历只读遍历into_values() 与 into_keys()容量、实际长度、判空导出清除重定容量 use std::collections::HashMap;创…...

使用SoapUI、Postman工具调用Webservice方法

SoapUI工具更适合调用Webservice使用。 1.使用SoapUI工具调用Webservice 创建“New SOAP Project” 自行定义一个项目名称&#xff0c;输入wsdl地址&#xff1a; 在左侧列表找到方法名&#xff0c;双击“Request 1”, 在请求数据中&#xff0c;添加对应的参数&#xff0c;然…...

js 与 C++引用和指针的关系

js 与 C引用和指针的关系 js 中既有引用的影子, 也有指针的影子。 1、引用用法 这里相当于C 中的引用, b是a的引用, 修改b ,a也改变。 var a { 1: 1 }var b a;a null;b[2] 2;console.error(b); // { 1: 1, 2: 2 }2、指针用法 这里 a,b应该按照指针理解。 var a undef…...

python --PyAibote自动化

官文: https://www.pyaibote.com/ 下载安卓集成环境: 可以看到开发的一些信息...

Ubuntu系统开发环境搭建

一&#xff0c;Android源码编译环境搭建 1 安装Java Development Kit (JDK) sudo apt-get update sudo apt-get install openjdk-8-jdk 2,确认JDK安装成功 java -version 3,安装编译所需的依赖项 sudo apt-get install git-core gnupg flex bison gperf build-essential zip cu…...

lvs-dr模式实验详解

华子目录 lvs-dr&#xff08;企业当中最常用&#xff09;dr模式数据逻辑dr模式数据传输过程dr模式的特点实验拓扑实验主机准备解决vip响应问题限制响应级别:arp_ignore限制通告级别:arp_announce 实验步骤1.client的ip设定2.router上的ip设定3.router开启路由转发功能4.lvs主机…...

【RDMA】mlxconfig修改和查询网卡(固件)配置--驱动工具

目录 简介 工具要求 语法 例子和参数 例子 更多参数 其他工具和查询 简介 mlxconfig 工具允许用户在不重新烧录固件的情况下更改某些设备配置。 配置在重启后仍然保留。 默认情况下&#xff0c;mlxconfig 显示将在下次启动时加载的配置。对于第五代设备&#xff0c;还…...

AI代码库问答引擎Folda-Scan

简介 什么是 Folda-Scan &#xff1f; Folda-Scan 是一款革命性的智能项目问答工具&#xff0c; 完全在浏览器中本地运行 。它使用高级语义矢量化将您的代码库转变为对话伙伴&#xff0c;使代码理解和 AI 协作变得前所未有的简单和安全。其采用尖端的 Web 技术和 AI 算法构建&…...

Python基础:文件简单操作

&#x1f343;引言 手把手带你快速上手Python Python基础专栏 一、&#x1f343;文件是什么 变量是把数据保存到内存中. 如果程序重启/主机重启, 内存中的数据就会丢失。 要想能让数据被持久化存储, 就可以把数据存储到硬盘中. 也就是在文件中保存。 通过文件的后缀名, 可以看…...

SpringBoot插件化架构的4种实现方案

在复杂业务场景下&#xff0c;传统的单体应用架构往往面临着功能扩展困难、代码耦合严重、迭代效率低下等问题。 插件化架构作为一种模块化设计思想的延伸&#xff0c;能够使系统具备更好的扩展性和灵活性&#xff0c;实现"热插拔"式的功能扩展。 本文将介绍Spring…...

使用VSCode在WSL和Docker中开发

通过WSL&#xff0c;开发人员可以安装 Linux 发行版&#xff08;例如 Ubuntu、OpenSUSE、Kali、Debian、Arch Linux 等&#xff09;&#xff0c;并直接在 Windows 上使用 Linux 应用程序、实用程序和 Bash 命令行工具&#xff0c;不用进行任何修改&#xff0c;也无需使用传统虚…...

MUX-VLAN基本概述

目录 1&#xff09;技术背景&#xff1a; 2&#xff09;基本概念&#xff1a; 3&#xff09;配置&#xff1a;进vlan视图下键入 1&#xff09;技术背景&#xff1a; 在企业网络中&#xff0c;各个部门之间网络需要相互独立&#xff0c;通常使用VLAN技术可以实现这一要求。如果企…...

深度学习篇---face-recognition的优劣点

face_recognition库是一个基于 Python 的开源人脸识别工具,封装了 dlib 库的深度学习模型,具有易用性高、集成度强的特点。以下从技术实现、应用场景等维度分析其优劣势: 一、核心优势 1. 极简 API 设计,开发效率极高 代码量少:几行代码即可实现人脸检测、特征提取和比对…...

Spring Boot的启动流程,以及各个扩展点的执行顺序

目录 1. 初始化阶段执行顺序 1.1 Bean的构造方法&#xff08;构造函数&#xff09; 1.2 PostConstruct 注解方法 1.3 InitializingBean 的 afterPropertiesSet() 1.4 Bean(initMethod "自定义方法") 2. 上下文就绪后的扩展点 2.1 ApplicationContext 事件监听…...

机器学习算法:逻辑回归

1. 基础概念 定义&#xff1a; 逻辑回归&#xff08;Logistic Regression&#xff09;是一种用于解决二分类问题的监督学习算法&#xff0c;通过概率预测样本属于某一类别的可能性。 核心特点&#xff1a;输出是概率值&#xff08;0~1&#xff09;&#xff0c;通过阈值&#…...

MaxCompute开发UDF和UDTF案例

文章目录 一、Java开发UDF1、创建Maven项目2、创建UDF类3、打包上传资源4、创建函数MyUDF5、SQL验证 二、Java开发UDTF1、创建Maven项目2、创建UDTF类3、打包上传更新资源4、创建函数MyUDTF5、SQL验证 三、常见问题1、发布函数报错 一、Java开发UDF 1、创建Maven项目 创建Mav…...

【从0-1的HTML】第2篇:HTML标签

文章目录 1.标题标签2.段落标签3.文本标签brbstrongsubsup 4.超链接标签5.图片标签6.表格标签7.列表标签有序列表ol无序列表ul定义列表dl 8.表单标签9.音频标签10.视频标签11.HTML元素分类块级元素内联元素 12.HTML布局13.内联框架13.内联框架 1.标题标签 标题标签&#xff1a…...