首页 > 编程语言 >KMP算法 Java实现

KMP算法 Java实现

时间:2024-04-17 13:34:08浏览次数:32  
标签:Java charAt int pattern 复杂度 回溯 next 算法 KMP

Problem: 28. 找出字符串中第一个匹配项的下标

目录

解题方法

  1. 构建next串
  2. 回溯查找next串,最后下标

思路

  1. 通过最大前缀后缀能找到下一次未查找到后要回溯的位置

构建next数组

无论如何第一个数的下一次回溯位置肯定是0,因此next[0]=0
这里的 j表示前缀起始位置 i表示后缀起始位置
如果找到字符不相同到的话,就让他一直回溯找,并且回溯赋值j = next[j-1]
能找到相同字符的话就直接i++,j++,并且把next[i] = j
这里先写while判断不相同 后写相同,是因为不相同的终点
一定是有相同的后缀或者直接结束查找(到了字符串末尾)

回溯查找

其实和上面的思路差不多,不能查找相同字符就一直回溯,能的话就共同前进,直到j到了模式串长度
这时因为i也在前进,所以i的下标是 应该返回的下标+(匹配串的长-1)

复杂度

时间复杂度:

添加时间复杂度, 示例: $O(m+n)$

空间复杂度:

添加空间复杂度, 示例: $O(m)$

Code

class Solution {

    public int strStr(String haystack, String needle) {
        return new KMP(needle).search(haystack);
    }

    public class KMP {
        private String pattern;   // 模式串
        private int[] next;
        public KMP(String pattern){
            this.pattern = pattern;
            int m = pattern.length();
            // 创建next 数组
            next = new int[m];
            next[0] = 0;
            for(int i = 1,j=0; i < m; i++){
                while(j>0&&pattern.charAt(i)!=pattern.charAt(j)){
                    j = next[j-1];
                }
                if(pattern.charAt(i) == pattern.charAt(j)){
                    j++;
                }
                next[i] = j;
            }
        }

        public int search(String text){
            int j = 0;
            for(int i=0;i<text.length();i++){
                while(j>0&&text.charAt(i) != pattern.charAt(j)){
                    j = next[j-1];
                }
                if(text.charAt(i) == pattern.charAt(j)){
                    j++;
                }
                if(j == pattern.length()){
                    return i-pattern.length()+1;
                }
            }
            return -1;
        }
    }

}

标签:Java,charAt,int,pattern,复杂度,回溯,next,算法,KMP
From: https://www.cnblogs.com/xiaofengs/p/18140402

相关文章

  • Python 数据结构和算法实用指南(三)
    原文:zh.annas-archive.org/md5/66ae3d5970b9b38c5ad770b42fec806d译者:飞龙协议:CCBY-NC-SA4.0第七章:哈希和符号表我们之前已经看过数组和列表,其中项目按顺序存储并通过索引号访问。索引号对计算机来说很有效。它们是整数,因此快速且易于操作。但是,它们并不总是对我们很有效......
  • Python 数据结构和算法实用指南(一)
    原文:zh.annas-archive.org/md5/66ae3d5970b9b38c5ad770b42fec806d译者:飞龙协议:CCBY-NC-SA4.0前言数据结构和算法是信息技术和计算机科学工程学习中最重要的核心学科之一。本书旨在提供数据结构和算法的深入知识,以及编程实现经验。它专为初学者和中级水平的研究Python编......
  • Python 数据结构和算法实用指南(二)
    原文:zh.annas-archive.org/md5/66ae3d5970b9b38c5ad770b42fec806d译者:飞龙协议:CCBY-NC-SA4.0第四章:列表和指针结构我们已经在Python中讨论了列表,它们方便而强大。通常情况下,我们使用Python内置的列表实现来存储任何数据。然而,在本章中,我们将了解列表的工作原理,并将研......
  • 2.JAVA入门 了解JAVA 配置环境
    Java入门Java特性和优势简单性:Java语言设计简洁,易于学习和使用。它摒弃了许多复杂的特性和语法,使得编程变得更加直观和容易上手。面向对象:Java是一种纯粹的面向对象编程语言,所有的代码都以类和对象的形式组织。这种面向对象的特性使得代码更加模块化、可重用性更高,并且更容易......
  • js带注释的冒泡排序算法
    一、简述冒泡排序(BubbleSort)是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果二者的顺序(如从大到小、首字母从A到Z)错误就交换。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。这个算法......
  • 基于Redis实现基本抢红包算法
    简介:[key,value]的缓存数据库,Redis官方性能描述非常高,所以面对高并发场景,使用Redis来克服高并发压力是一个不错的手段,本文主要基于Redis来实现基本的抢红包系统设计.发红包模块:1:发红包模块流程图如下:  用户首先输入红包金额和红包个数,然后生成当前红......
  • day14_我的Java学习笔记 (常用API、Lambda、常见算法)
    1.常用API1.1Date类【案例】:计算出当前时间往后走1小时121秒之后的时间是多少。1.2SimpleDateFormat【练习】:秒杀活动1.3Calendar2.JDK8新增日期类2.1概述、LocalTime/LocalDate/LocalDateTime2.2Ins......
  • IDEA2023版本创建Spring项目只能勾选17和21却无法使用Java8的完美解决方案
    参考:https://www.jb51.net/program/308256k4b.htm方案一:替换创建项目的源我们只知道IDEA页面创建Spring项目,其实是访问springinitializr去创建项目。故我们可以通过阿里云国服去间接创建Spring项目。将https://start.spring.io/或者http://start.springboot.io/替换为https://......
  • day12_我的Java学习笔记 (package包、权限修饰符_private+缺省+protected+public、fin
    1.包IDEA配置自动导包:2.权限修饰符同一个类中的,【private、缺省、protected、public】都可以访问同一个包中的其他类,【private】不可以访问,【缺省、protected、public】都可以访问不同包下的无关类,【private、缺省、protected】都不可以访问,只有【public......
  • 基于yolov2深度学习网络的螺丝螺母识别算法matlab仿真
    1.算法运行效果图预览 2.算法运行软件版本matlab2022a 3.算法理论概述      在工业自动化和质量控制领域,准确且高效的螺丝螺母识别至关重要。深度学习方法,特别是基于卷积神经网络(CNN)的目标检测技术,因其卓越的特征提取能力,成为解决此类问题的有效手段。YOLOv2......