【594 · 字符串查找 II】

594 · 字符串查找 II

困难 | 30% 通过率 | 要求 O(n + m)

→ 标准「KMP 模板题」。

继续用「快刷四部曲」5 分钟背完、一辈子会用。


第一步:识别模式

  • 题型:单模式串精确匹配
  • 模式:KMP(Knuth--Morris--Pratt)
  • 关键 :预处理 next[] 数组,失配时 不回退主串指针
  • 复杂度 :预处理 O(m) + 匹配 O(n) = O(n + m),空间 O(m)

第二步:选择模板

KMP 双函数固定写法:

  1. buildNext(String p) → 返回 next[]
  2. strStr(String s, String p) → 返回首位置或 -1

第三步:注意边界

  • 空模式串:约定返回 0(与 Java 内置 indexOf 一致)
  • 主串长度 n、模式串长度 m,m > n 时直接 -1
  • next[] 长度 = m,next0 = -1(经典 -1 写法最简洁)

第四步:成功秒杀(完整代码)

java 复制代码
public class Solution {
    /**
     * @param source: the source string
     * @param target: the target string
     * @return: the first index of target in source, or -1 if not exist
     */
    public int strStr(String source, String target) {
        if (target == null || source == null) return -1;
        int n = source.length(), m = target.length();
        if (m == 0) return 0;          // 空模式串约定返回 0
        if (m > n) return -1;          // 剪枝

        int[] next = buildNext(target);
        int i = 0, j = 0;              // i 指向 source,j 指向 target
        while (i < n) {
            if (j == -1 || source.charAt(i) == target.charAt(j)) {
                i++; j++;
            } else {
                j = next[j];           // 失配,j 回退
            }
            if (j == m) {              // 完全匹配
                return i - j;
            }
        }
        return -1;
    }

    // 预处理 next 数组,next[0] = -1
    private int[] buildNext(String p) {
        int m = p.length();
        int[] next = new int[m];
        next[0] = -1;
        int i = 0, j = -1;
        while (i < m - 1) {
            if (j == -1 || p.charAt(i) == p.charAt(j)) {
                i++; j++;
                next[i] = j;
            } else {
                j = next[j];
            }
        }
        return next;
    }
}

复杂度

  • 时间:O(n + m)
  • 空间 :O(m) 仅 next[]

背下 buildNext + strStr 双函数,以后任何「单模式串匹配」困难题直接秒。

相关推荐
午彦琳10 分钟前
2026.9.17
数据结构·算法·leetcode
西峰u11 分钟前
Java单例模式|从基础到多线程安全
java·java单例模式
ClinicTech13 分钟前
实验室洗瓶机的清洗系统架构与自动化控制解析
java·python
linmengmeng_131427 分钟前
【总结】MyBatis-Plus批量插入与清表的正确姿势
java·spring boot·mysql·mybatis
木井巳32 分钟前
【记忆化搜索】不同路径
java·算法·leetcode·深度优先·剪枝·推荐算法
Sam_Deep_Thinking33 分钟前
new Thread()之后发生了什么?
java·后端·面试·程序员
泡海椒33 分钟前
规则引擎对比:JQuick-Java vs Drools 轻量场景选型对比
java·开发语言
wno7041 小时前
Spring Security短信验证码登录
java·python·spring
泡泡鱼(敲代码中)1 小时前
Python 容器类型学习笔记:列表、元组、字典、集合
开发语言·笔记·python·pycharm
步行cgn1 小时前
Spring util 命名空间详解
java·后端·spring