【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,next[0] = -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 双函数,以后任何「单模式串匹配」困难题直接秒。

相关推荐
杜子不疼.3 分钟前
【C++ AI 大模型接入 SDK】 - DeepSeek 模型接入(上)
开发语言·c++·chatgpt
加号39 分钟前
【C#】 串口通信技术深度解析及实现
开发语言·c#
sycmancia1 小时前
Qt——编辑交互功能的实现
开发语言·qt
RyFit1 小时前
SpringAI 常见问题及解决方案大全
java·ai
石山代码1 小时前
C++ 内存分区 堆区
java·开发语言·c++
心中有国也有家1 小时前
cann-recipes-infer:昇腾 NPU 推理的“菜谱集合”
经验分享·笔记·学习·算法
绝知此事2 小时前
【算法突围 01】线性结构与哈希表:后端开发的收纳术
java·数据结构·算法·面试·jdk·散列表
无风听海2 小时前
C# 隐式转换深度解析
java·开发语言·c#
碧海银沙音频科技研究院2 小时前
通话AEC与语音识别AEC的软硬回采链路
深度学习·算法·语音识别
一只大袋鼠2 小时前
Git 进阶(二):分支管理、暂存栈、远程仓库与多人协作
java·开发语言·git