力扣面试经典算法150题:找出字符串中第一个匹配项的下标

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

今天的题目是力扣面试经典150题中的数组的简单题: 找出字符串中第一个匹配项的下标

题目链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/?envType=study-plan-v2&envId=top-interview-150

题目描述

给定一个字符串 haystack 和一个字符串 needle,请找出 needle 在 haystack 中第一次出现的位置(下标)。如果 needle 不是 haystack 的一部分,则返回 -1。

  • 示例:
    • 输入:
      haystack = “hello”, needle = “ll”
    • 输出:
      2
    • 输入:
      haystack = “aaaaa”, needle = “bba”
    • 输出:
      -1

题目分析

题目要求我们在一个字符串 haystack 中找到另一个字符串 needle 第一次出现的位置。如果 needle 不是 haystack 的一部分,则返回 -1。

很明显,字符串needle是被包含在haystack中的一个子串,这意味着needle的字符在haystack中连续出现。

只需要第一次出现的位置则意味着我们需要的结果是needle中的字符第一次在haystack中连续出现时的第一个字符在haystack中的下标。

解题思路

分隔法

第一时间想到的办法:

  1. 判断haystack是否包含needle,不包含直接返回-1。
  2. 判断haystack是否以needle开头, 是的话返回0。
  3. 使用needle分割haystack,获取第一段的字符串长度返回即可。

整串匹配法

在分割法之后再思考想到的办法,使用整个子串去匹配:

  1. 获取两个字符串的长度。
  2. 以两者差值作为循环条件进行循环。
  3. 截取当前下标开始到子串长度的字符串与子串对比,一致则返回下标的值。
  4. 返回-1。

单字符匹配法:

在整串匹配法后想到的,不截取字符串,直接依次比较每个字符:

  1. 获取两个字符串的长度。
  2. 以两者差值作为循环条件进行循环
  3. 从 haystack 的第一个字符开始,逐个字符比较。
  4. 如果发现 haystack 中有一段子串与 needle 相同,则返回这段子串的起始位置。
  5. 如果遍历完整个 haystack 都没有找到匹配的子串,则返回 -1。

KMP 算法:

在上诉方法用完以后,尝试找到该类型题目的特殊算法:

  1. 构建 KMP 的 next 数组,然后根据 next 数组进行快速匹配。
  2. 如果找到匹配的子串,则返回起始位置;否则,返回 -1。

有点抽象,没完全想明白,这里就不贴了。。。

实际算法代码

下面是使用三种方法的 Java 实现:

public static void main(String[] args) {
        StrStr solution = new StrStr();

        // 示例数据
        String haystack = "hello";
        String needle = "ll";

        // 调用计算第一个匹配项下标的方法
        int index1 = solution.strStr1(haystack, needle);
        int index2 = solution.strStr2(haystack, needle);
        int index3 = solution.strStr3(haystack, needle);

        // 输出结果
        System.out.println("The index1 of the first occurrence is: " + index1);
        System.out.println("The index2 of the first occurrence is: " + index2);
        System.out.println("The index3 of the first occurrence is: " + index3);
    }

    /**
     * 查找字符串中第一个匹配项的下标: 分割法
     *
     * @param haystack 主字符串
     * @param needle   子字符串
     * @return 第一个匹配项的下标
     */
    public int strStr1(String haystack, String needle) {
        if (needle.isEmpty()) {
            return 0;
        }

        if (!haystack.contains(needle)) {
            return -1;
        }
        if (haystack.startsWith(needle)) {
            return 0;
        }
        String[] split = haystack.split(needle);
        if (split.length > 0) {
            return split[0].length();
        }
        return -1;
    }


    /**
     * 查找字符串中第一个匹配项的下标:整串匹配法
     *
     * @param haystack 主字符串
     * @param needle   子字符串
     * @return 第一个匹配项的下标
     */
    public int strStr2(String haystack, String needle) {
        if (needle.isEmpty()) {
            return 0;
        }

        int n = haystack.length();
        int m = needle.length();

        for (int i = 0; i <= n - m; i++) {
            if (needle.equals(haystack.substring(i, i + m))) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 查找字符串中第一个匹配项的下标:单字符匹配法
     *
     * @param haystack 主字符串
     * @param needle   子字符串
     * @return 第一个匹配项的下标
     */
    public int strStr3(String haystack, String needle) {
        if (needle.isEmpty()) {
            return 0;
        }

        int n = haystack.length();
        int m = needle.length();

        for (int i = 0; i <= n - m; i++) {
            boolean found = true;
            for (int j = 0; j < m; j++) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    found = false;
                    break;
                }
            }
            if (found) {
                return i;
            }
        }

        return -1;
    }

结果

同时调用三个方法,返回结果都符合预期:

在这里插入图片描述

我们分别提交到力扣:

在这里插入图片描述
通过肯定都是通过的,这里贴第三种方法的图,因为这个方法的相对最优。

以下是三种方法的提交结果:

  1. 分割法

在这里插入图片描述

  1. 整串匹配法

在这里插入图片描述

  1. 单字符匹配法

    在这里插入图片描述

三种方法最先能想到的容易程度以及理解难度正好按与算法的效果相反,难道这就是算法吗

在这里插入图片描述

总结

今天自己想了三种方法,特殊算法KMP有点抽象一下子还没想明白,有兴趣的自行学习,明天我再抽空理解一下。

另外数组简单难度的题目已经做完,下面开始上强度了。。。

加油!!!

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

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

相关文章

知识改变命运 数据结构【栈和队列面试题】

1.最小栈 class MinStack {Stack <Integer>stack;Stack <Integer>minStack; public MinStack() {stacknew Stack<>();minStacknew Stack<>();}public void push(int val) {stack.push(val);if(minStack.empty()) {minStack.push(val);} else {int top…

算法-IMM

trajectory-prediction程序的imm.cc中的以下代码的对应的算法原理在后面 void IMM_UKF::InputInteract() {if (std::isnan(model_pro_(0)) || std::isnan(model_pro_(1)) || std::isnan(model_pro_(2)))std::abort();if (model_pro_.sum() ! 0)model_pro_ / model_pro_.sum();…

Android 12系统源码_多屏幕(二)模拟辅助设备功能开关实现原理

前言 上一篇我们通过为Android系统开启模拟辅助设备功能开关&#xff0c;最终实现了将一个Activity显示到多个屏幕的效果。 本篇文章我们具体来分析一下当我们开启模拟辅助设备功能开关的时候&#xff0c;Android系统做了什么哪些操作。 一、模拟辅助设备功能开关应用位置 …

基于web框架的协同过滤的美食推荐系统【数据爬虫、管理系统、数据可更新、样式可调整】

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍研究背景研究的目的与意义协同过滤算法基于用户的协同过滤算法定义基于物品的协同过滤算法的定义 数据库设计db_food&#xff08;美食信息表&#xff09;db_collect&#xff08;美食…

【Kubernetes】k8s集群图形化管理工具之rancher

目录 一.Rancher概述 1.Rancher简介 2.Rancher与k8s的关系及区别 3.Rancher具有的优势 二.Rancher的安装部署 1.实验准备 2.安装 rancher 3.rancher的浏览器使用 一.Rancher概述 1.Rancher简介 Rancher 是一个开源的企业级多集群 Kubernetes 管理平台&#xff0c;实…

【Linux网络】select函数

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 select函数介绍select函数参数介绍select函数返回值select的工作流程TCP服务器【多路复用版】 select函数介绍 在Linux网络编程中&#xff0c;select 函数是一种非常有用的IO多路复用技术&#xff0…

基于springboot的车辆违章信息管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

鸿萌数据恢复服务:SQL Server 中的“PFS 可用空间信息不正确”错误

天津鸿萌科贸发展有限公司从事数据安全服务二十余年&#xff0c;致力于为各领域客户提供专业的数据恢复、数据备份、网络及终端数据安全等解决方案与服务。 同时&#xff0c;鸿萌是国际主流数据恢复软件(Stellar、UFS、R-Studio、ReclaiMe Pro 等)的授权代理商&#xff0c;为专…

RK3568笔记五十六:yolov8_obb旋转框训练部署

若该文为原创文章,转载请注明原文出处。 本文基于rknn_model_zoo和山水无移大佬的博客和代码训练模型并部署到正点原子的ATK-DLRK3568板子测试。 https://github.com/ultralytics/ultralytics 一、训练 1、环境搭建 使用的是AUTODL环境,yolov8-obb数据集不大,也可以使用c…

歌曲爬虫下载

本次编写一个程序要爬取歌曲音乐榜https://www.onenzb.com/ 里面歌曲。有帮到铁子的可以收藏和关注起来&#xff01;&#xff01;&#xff01;废话不多说直接上代码。 1 必要的包 import requests from lxml import html,etree from bs4 import BeautifulSoup import re impo…

代码块分类

局部代码块 public class Test {public static void main(String[] args) {{int a 10;}// 执行到此处时候,变量a已经从内存中消失了。 // System.out.println(a);} } 构造代码块 public class Test {private String name;private int age;{// 构造代码块System.out.…

c#实现数据导出为PDF的方式

PdfSharp vs iTextSharp: C#中PDF导出功能比较 PdfSharp 优点 轻量级&#xff1a;适合简单的PDF生成任务易于学习&#xff1a;API相对简单&#xff0c;学习曲线较缓开源&#xff1a;提供开源版本&#xff0c;可自由使用和修改纯C#实现&#xff1a;不依赖外部库或COM组件支持…

C:每日一练:单身狗(2.0版本)

前言&#xff1a; 今天在刷题的时候突然看到一道题&#xff0c;疑似一位故题。仔细一看&#xff0c;欸&#xff01;这不是就是单身狗的升级版吗&#xff1f;我想那必须再安排一篇&#xff0c;不过由于本篇文章与上一篇单身狗文章所涉及的知识点基本相同&#xff0c;所以还请大…

设计模式在芯片验证中的应用——状态

一、状态模式 状态模式是一种行为设计模式&#xff0c; 让你能在一个对象的内部状态变化时改变其行为&#xff0c; 使其看上去就像改变了自身所属的类一样。 在RTL中可能存在复杂的有限状态机FSM&#xff0c;在任何一个特定状态中&#xff0c; RTL的行为都不相同&#xff0c;…

【前缀和算法】--- 一维和二维前缀和模板

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 算法Journey 本文开始,博主开始讲解有关前缀和的算法&#xff0c;本篇博客我们先来了解一下有关前缀和的两个模板。 &#x1f3e0; 一维前缀和模板 &…

【网络】局域网LAN、广域网WAN、TCP/IP协议、封装和分用

文章目录 局域网 LAN广域网 WAN网络中的重要概念IP 地址端口号 认识协议协议分层是什么OSI 七层网络模型TCP/IP 五层网络模型&#xff08;或四层&#xff09;物理层传输层网络层数据链表层应用层网络设备所在分层 封装和分用[站在发送方视角]&#xff08;封装&#xff09;[站在…

邮票孔拼版制作方法

邮票孔拼版制作方法 拼版后的局部图:(中间用连接桥的方式&#xff0c;此方式能最少程度上减少残留) 2&#xff09;拼版后的效果图 3&#xff09;邮票孔拼版规则: 拼板与板间距1.2MM或者1.6MM 等邮票孔&#xff1a;8个0.55MM的孔,孔间距0.2MM加两排&#xff0c;邮票孔伸到…

linux服务 学习

服务&#xff08;Service&#xff09; 在Linux操作系统中&#xff0c;服务&#xff08;Service&#xff09;是一个基本概念&#xff0c;它通常指的是运行在后台的、持续提供特定功能或资源给系统内部组件或者网络上的客户端程序。 这些服务是系统正常运行和提供各种功能的关键…

【三维重建汇总】NeRF和GS重建中,如何排除干扰物?(提升质量)

汇总最近NeRF与GS提升质量的论文 文章目录 前言一、NeRF On-the-go&#xff1a;利用不确定性落地真实世界&#xff08;CVPR24&#xff09;摘要1.DINOv2特征的不确定性预测2.NeRF中干扰物去除的不确定性3.优化4. Dilated Patch 扩大采样5.实验结果 二、Pixel-GS:像素感知的梯度密…

关于nginx标准配置参数介绍

标准配置参数&#xff1a; user root;#配置用户或者组&#xff0c;默认为nobody worker_processes 4;#允许生成的进程数&#xff0c;默认为1 项目中nginx.conf配置文件 user root; worker_processes 4; //最大的进程数&#xff0c;要看服务器的内核是多少核的&#xff0…