Acwing831KMP字符串

题目

给定一个字符串 S,以及一个模式串 P,所有字符串中只包含大小写英文字母以及阿拉伯数字。

模式串 P 在字符串 S 中多次作为子串出现。

求出模式串 P 在字符串 S 中所有出现的位置的起始下标。

输入格式

第一行输入整数 N,表示字符串 P 的长度。

第二行输入字符串 P

第三行输入整数 M,表示字符串 S 的长度。

第四行输入字符串 S

输出格式

共一行,输出所有出现位置的起始下标(下标从 00 开始计数),整数之间用空格隔开。

数据范围

1≤N≤10^5 1≤M≤10^6

输入样例:

复制代码
3
aba
5
ababa

输出样例:

复制代码
0 2

代码

java 复制代码
import java.util.*;
class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        String p = in.next();
        int m = in.nextInt();
        String s = in.next();
        // p = p + " ";
        // s = s + " ";
        int[] ne = new int[n + 1];

        // 预处理模式串
        for (int i = 2, j = 0; i <= n; i++) {
            while (j > 0 && p.charAt(i - 1) != p.charAt(j)) j = ne[j];
            if (p.charAt(i - 1) == p.charAt(j)) j++;
            ne[i] = j;
        }

        StringBuilder result = new StringBuilder();

        // 在目标串中搜索模式串
        for (int i = 1, j = 0; i <= m; i++) {
            while (j > 0 && s.charAt(i - 1) != p.charAt(j)) j = ne[j];
            if (s.charAt(i - 1) == p.charAt(j)) j++;
            if (j == n) {
                result.append(i - n).append(" ");  // 将匹配的位置添加到StringBuilder中,一次性输出,解决超时问题
                j = ne[j];
            }
        }
        System.out.print(result.toString());

    }
}
相关推荐
我是一颗柠檬3 分钟前
【MySQL全面教学】MySQL聚合函数与分组Day5(2026年)
数据库·后端·mysql·database
星栈独行3 分钟前
别让 API 跳去登录页:我在 Axum 里做了认证失败双通道
前端·后端·rust·开源·github·个人开发
JaguarJack6 分钟前
TrueAsync Server 为 PHP 带来了原生的高性能 HTTP 服务器
后端·php
字节高级特工18 分钟前
Redis事务:简单但实用的打包执行
数据库·redis·后端·缓存
极客小云20 分钟前
【用 Go 写一个统一的 LLM Token 统计库:tokencalc 的设计与实现】
开发语言·后端·golang
Vect__22 分钟前
C++转go的之路:变量声明、iota、函数、切片、init、defer
开发语言·后端·golang
fengxin_rou22 分钟前
【SpringBoot+Elasticsearch 内容搜索系统实战】:架构设计与全流程实现
spring boot·后端·elasticsearch
还是鼠鼠1 小时前
AI掘金头条新闻系统 (Toutiao News)-用户注册-生成Token
后端·python·mysql·fastapi·web
自珍JAVA7 小时前
访问者模式:让你的代码优雅地“拜访”对象结构
后端
毅航10 小时前
AI 浪潮下,会用工具不等于具备能力
后端·程序员·ai编程