LeetCode28.找出字符串中第一个匹配项

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

仅由小写英文字符组成


思路 一

朴素匹配

顾名思义最简单的匹配方式但是时间复杂度较高

首先将字符串通过toCharArray函数转为数组

for循环定义 i 指针指向hayStack数组的起始位置,索引在 0 \~ (n - m + 1)内遍历

嵌套while循环 如果字符匹配则 a ,b 指针继续同时向前

直到b = m或者 指针指向的内容不相同

最后返回 i 指针

java 复制代码
class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length();
        int m = needle.length();
        //字符串转成数组
        char[] hay = haystack.toCharArray();
        char[] ned = needle.toCharArray();

        for (int i = 0; i <= n - m; i++){
            int a = i, b = 0;
            while (b < m && hay[a] == ned[b]){
                ++a;
                ++b;
            }
            //如果能够完全匹配。返回原串的发起点下标
            if(b == m) return i;

        }
        return -1;
    }
}

思路二

KMP算法

没啥好说的,写原理的帖子很多

当模版背下来就好

java 复制代码
class Solution {
    //KMP算法,源串为 string, 匹配串为pattern
    //不管何时,string的指针不回溯
    //pattern的指针有条件地回溯
    public int strStr(String haystack, String needle) {
        if (needle.length() == 0) return 0;
        int[] next = new int[needle.length()];
        getNext(next, needle);
 
        int j = 0;
        for (int i = 0; i < haystack.length(); i++) {
            while (j > 0 && needle.charAt(j) != haystack.charAt(i)) 
            //j指针回溯
                j = next[j - 1];
            if (needle.charAt(j) == haystack.charAt(i)) 
                j++;
            if (j == needle.length()) 
                return i - needle.length() + 1;
        }
        return -1;

    }
    
    //寻找nxet数组
    private void getNext(int[] next, String s) {
        int j = 0;
        next[0] = 0;
        for (int i = 1; i < s.length(); i++) {
            while (j > 0 && s.charAt(j) != s.charAt(i)) 
            //如果 s.charAt(j) 和 s.charAt(i) 不相等,说明当前位置匹配失败,需要回溯到前一个可能匹配的位置,即 j = next[j - 1]。
                j = next[j - 1];
             //如果 s.charAt(j) 和 s.charAt(i) 相等,说明找到了一个更长的重复前缀和后缀,将 j 的值增加 1。
            if (s.charAt(j) == s.charAt(i)) 
                j++;
            //将 j 的最新值赋给 next[i],表示在位置 i 处的字符之前的最长重复前缀和后缀的长度。
            next[i] = j; 
        }
    }
}

NEXT数组演示

相关推荐
文丑颜不良啊7 分钟前
LeetCode2481~2500题目解析
java·leetcode
Flynn Liang1 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
聪明的笨猪猪2 小时前
实际工程问题:AI 生成 Spring Cache(@Cacheable / @CachePut / @CacheEvict)缓存注解踩坑
java·经验分享·面试·ai编程
愿有所息2 小时前
记一次 ARM64 + JDK8 上 fastjson2 的诡异数据错乱
java
秋饼2 小时前
MCP 2026-07-28 无状态协议大改版:Spring AI 2.1 多轮往返请求与网关路由落地
java·ai·技术分享·后端开发
SL_staff4 小时前
JVS-BI 实战:业务人员如何用零代码 ELT + 可视化配置构建实时经营分析闭环
java·spring·全栈
SL_staff4 小时前
企业AI落地难?JVS-AI渐进式实践:安全可控、小切口验证、标准化沉淀与规模化复制
java·开源·aigc
武子康4 小时前
驾驶轨迹换个坐标,就能给移动机器人用吗?
人工智能·算法·机器学习
David猪大卫4 小时前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
SL_staff5 小时前
JVS数字底座实践:构建企业级统一内容管理平台的技术路径
java·产品