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

[LeetCode]day27 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 。

提示:

1 <= haystack.length, needle.length <= 104
haystack 和 needle 仅由小写英文字符组成

题解

1.暴力解法

思路:

  • 双指针扫描:
    – i指针遍历主串
    – j指针遍历模式串
  • 逐字符比对
    –当 haystack[i] == needle[j] 时,双指针共同前进
    –出现不匹配时,i 回溯到本次匹配的起始位置+1,j 重置为0
  • 终止条件
    –若 j 走完整个模式串 → 匹配成功,返回 i-j
    –若 i 走完主串但 j 未走完 → 匹配失败,返回-1
    请添加图片描述

自己写

class Solution {
public:
    int strStr(string haystack, string needle) {
        int i=0,j=0;
        while(i<=haystack.size()-needle.size()){
            if(haystack[i]==needle[j]){
                i++;
                j++;
                if(j==needle.size()){
                    return i-j;
                }
            }else{
                i=i-j+1;
                j=0;
            }
        }
        return -1;
    }
};

问题在于while(i<=haystack.size()-needle.size())
我本来的想法是当主串剩余的字符数比子串还少时,肯定不能匹配成功了,但是在匹配过程中i可能会大于haystack.size()-needle.size()

正确版本代码

 class Solution {
public:
    int strStr(string haystack, string needle) {
        int i=0,j=0;
        while(i<haystack.size()&& j<needle.size()){
            if(haystack[i]==needle[j]){
                i++;
                j++;
            
            }else{
                i=i-j+1;
                j=0;
            }
        }
        return j==needle.size()?(i-j):-1;
       
    }
};

KMP算法

核心难点在于求Next数组,Next数组用于next数组用于记录模式串中每个位置的最长公共前后缀长度

求next数组思路

  • 初始化Next数组
  • 处理元素不相同情况
  • 处理元素相同情况
  • 更新next数组

strStr函数思路

  • 初始化:
    主串指针i = 0,模式串指针j = 0。
    调用getNext函数构造next数组。
  • 匹配逻辑:
    遍历主串haystack:
    –如果j > 0且haystack[i] != needle[j],说明当前字符不匹配,模式串指针j回溯到next[j - 1]。
    –如果haystack[i] == needle[j],说明当前字符匹配,j加1。
    –如果j等于模式串的长度(j == needle.size()),说明模式串完全匹配,返回匹配的起始位置i - j + 1
  • 返回值:
    如果匹配成功,返回模式串在主串中的起始位置。
    如果匹配失败,返回-1。

代码书写

class Solution {
public:
    void getNext(int*next,const string& s){
        //1.初始化
        next[0]=0;
        int i=1,j=0;
        for(i=1;i<s.size();i++){
          //2.处理不相同 回溯
          while(j>0&&s[i]!=s[j]){
            j=next[j-1];
          }
          //3.处理相同
          if(s[i]==s[j])
            j++;
            //4.更新Next数组
           next[i]=j;
    }
    } 
    int strStr(string haystack, string needle) {
        //i作为主串的指针,j作为模式串的指针
       int i=0,j=0;
       vector<int> next(needle.size());
       getNext(&next[0],needle);
       for(;i<haystack.size();i++){
        while(j>0&&haystack[i]!=needle[j]){
                j=next[j-1];
        }
        if(haystack[i]==needle[j])
        j++;
        if(j==needle.size()){
            return i-j+1;
        }
       }
       return -1;
    }
};
易错点
  • 求next数组时,在处理不相同情况while(j>0&&s[i]!=s[j])是使用while而不是if
    请添加图片描述

相关文章:

  • 音视频入门基础:RTP专题(10)——FFmpeg源码中,解析RTP header的实现
  • Docker仿真宇树狗GO1
  • Spring Security+JWT+Redis实现项目级前后端分离认证授权
  • 【DeepSeek-R1背后的技术】系列九:MLA(Multi-Head Latent Attention,多头潜在注意力)
  • 深入解析适配器模式:软件架构中的接口协调大师
  • printf和 vprintf的区别
  • MongoDB学习
  • CASS11快捷键设置
  • 国内三大知名开源批发订货系统对比
  • 【React】React 基础(2)
  • 深度解读DeepSeek:从原理到模型
  • Cursor不能白嫖还不安全:Cline + DeepSeek V3,最强国产双开源解决方案
  • C语言内存函数
  • 【MATLAB例程】RSSI/PLE定位与卡尔曼滤波NLOS抑制算法,附完整代码
  • 智能自动化新纪元:AI与UiPath RPA的协同应用场景与技术实践
  • vscode软件中引入vant组件
  • leetcode hot100-34 合并K个升序链表
  • 什么是Firehose?它的作用是什么?
  • 蓝桥杯笔记——递归递推
  • FTP 实验(ENSP模拟器实现)
  • 现场丨“影像上海”启幕:串联摄影、电影与当代艺术
  • 北上广深均宣布下调个人住房公积金贷款利率
  • 泉州一家婚介机构广告牌越南新娘七天闪婚领证?市监部门介入
  • 太原一高中生指出博物馆多件藏品标识不当,馆方已邀请他和专家共同探讨
  • 超燃!走过莫斯科街头的“中国排面”
  • 万里云端遇见上博--搭乘“上博号”主题飞机体验记