基础算法系列--[基本数据结构KMP]

news2025/7/4 6:16:04

文章目录

  • 前言
  • 链表
    • 单链表
    • 双链表
  • 栈和队列
    • 队列
    • 单调
  • KMP

前言

今天要搞的是基本的一些数据结构,当然咱们这个不是那么“正经”。当然今天也没啥代码,因为太简单了(其实我也想水一下~)

链表

单链表

单链表这个东西,应该都知道,就是一个这个玩意:
在这里插入图片描述
好处:

  1. 可以一直存嘛
  2. 方便在后面插入元素嘛
    但是缺点呢,在这里的话我们原来是用Node然后用next指针去指向下一个元素来做。但是这个node是一个自定义的一个结构,这样就导致每次需要创建比较麻烦。

那么我们这边就是说用数组去模拟这个链表,同样的这个数组可以是动态的比如Java里面的ArrayList或者直接Python里面的,当然用python的选择要更多。
总之为了高效嘛,我们用数组来实现呗,只要我具备了单链表的特质,你管我怎么实现是吧。

那么这个怎么干呢:

在这里插入图片描述
其实就这样干就完了。

一开始value的第一个元素就是头结点,这里我们也是需要一个head,也就是头结点,有可能删除头结点(一开始的)所以还是需要这个head,因为删除没有办法真的删除,或者说如果要删除,问题就很慢了,换一句话说,适合解题,我们的目的也是解题。

双链表

至于这个双链表的话,那就是再加入一个数组存储pre就好了
在这里插入图片描述

栈和队列

OK,接下来的话,我们再来看到这个栈还队列,同样的我们要使用这个数组来做一个模拟。这个的话其实更加简单,这里的话我们就直接看到伪代码好吧:

这里我们用C++的伪代码来写一下,这个更直观一点:

#include<iostream>
using namespace std;
const int N =2022;

int stk[N],tt;
//insert
stk[++t]=x;
//pop
tt--;
if(tt>0)
	not empty
else
	empty
//stack top
stk[tt];

差不多就这样一个栈就好了

队列

队列的话也是一样类似的

#include<iostream>
using namespace std;
const int N=2022;
int q[N],hh,tt=-1;

//insert
q[++tt]=x
// out 
hh++;

if(hh<=tt)
	not empty
else
	empty
//get head
q[hh];
//get end
q[tt]

单调

然后说完了这个的话,有啥用呢,首先这个的话会比较快,当然缺点也就是刚刚那个嘛,是一个伪删除。不过这个也无所谓,能够快速执行就完了。然后的好处呢就是快,毕竟比较原始的玩意嘛。

然后的话这里面用自己写的这种栈,队列之类的话,用单调队列,单调栈的时候的话,可以比较好的考虑到这个。

像一些滑动窗口的题目可以考虑用单调队列去做,去年的时候,好像做过一道题目来自,好像是在letcode里面。这里的话我就不去找例题了。就单纯说一下思想吧。
首先单调栈,单调队列其实都是类似的。核心其实就是利用单调的一些性质,或者利用马尔科夫性。
那么这个玩意的话大概其实就是这样的。
假设有这样的一种题目,给你一个序列,然后呢,叫你找到每一个数字中左边最近的最小的数,或者最大的数字的时候。那么这个时候的话我们可以考虑直接使用单调栈,假设找最小的。那么你只需要准备一个栈。每次遍历的时候呢,去栈里面判断,把栈里面的比他小的元素输出就好了。也就是说,你只要保证你的栈,是单调递增的就可以。为什么这样就可以呢,我们可以简单画一个数轴:
在这里插入图片描述
这个的话大概有点抽象,反正就是这个意思。

还有就是使用单调队列的一种题目,这个的话原理大概也是类似的。找不到原题了,我大概描述一下是这样的:
给一个数列,在区间大小为K的子数列里面找到找到最小值,从左到右依次序滑动。

那么这个题目的思路其实是类似的,保证单调就好了,这里保证队头最小就好了,然后输出队头的元素。但是比较特殊的就是,也是因为我们的这个删除问题,我们的队列里面得存储下标就好了。用这个的原因的话,就是为了避免重复的一个比较,重复的排序。画一个数轴表示大概是这样的:
在这里插入图片描述
没找到原题,这个代码暂时就先这样吧。

KMP

这个算法的话,算了,还是说一下吧。

这个的话,其实挺简单的,搞清楚它的一个核心思想其实就很简单了,我们先不管什么前缀,后缀,什么乱七八糟的概念。从简,我就就直接看到最朴素的做法。然后从朴素的做法里面去找到它的一个思想,就是怎么偷懒。
在这里插入图片描述

这样的话,我们不就偷到一点懒了嘛。
这个不就是大部分男人滴最爱“KMP”嘛(像博主一样及其关注了博主的帅小伙除外)

那么搞清楚了,我们要想办法用这种方式来偷懒,那么我们就可以很好滴搞清楚这个KMP算法了。

OK,那么我们要做的呢就是说如何去想办法知道,最长的玩意,那么我们这边有一个数组叫做next数组,在kmp算法里面。

那么这个数组是什么玩意呢,他其实是这样的:

next[i]=j

这个是什么意思呢,就是说这样

Str[1~j]=Str[i-j+1,i]

假设从开始,第i个字符前的j个字符连起来和字符一开始到第j个字符是一样的。

这个就是所谓next数组,那么这个时候的话,有两个点第一个点就是怎么用这个next,然后就是如何求取next。
首先是怎么用。用的话非常简单,其实就是说,对比被,假设P是我们的被匹配的字符串,S是我们用来匹配的字符串(就是图里面的蓝色的线)。当在P当中的第i个字符和我们匹配字符串的第j个字符不相等的时候,那么前面的j-1字符是和前面的i-1都是相等的对吧。假设现在next[j-1]=3,那么意味着前面三个字符和头部的三个字符都是相等的对吧,再假设下标是从0开始的,那么这个时候,我们P字符串的第i个元素,是不是只需要从S字符串的下标为3的那个字符再开始比较就好了。因为第i-1,i-2,i-3和我们的S的0,1,2(下标)的字符是相等的。

所以用的话你会发现是这样用的:
(这个是以前的java代码)

      for (int i = 0, j = 0; i < n; i++) {
            while (j > 0 && haystack.charAt(i) != needle.charAt(j)) {
                j = next[j - 1];//有冲突
            }
            if (haystack.charAt(i) == needle.charAt(j)) {
                j++;
            }
            if (j == m) {
                return i - m + 1;
            }
        }
        return -1;


之后的话就是Next数组的一个求法。这个我们先直接看到代码:

        int[] next = new int[m];
        for (int i = 1, j = 0; i < m; i++) {
            while (j > 0 && needle.charAt(i) != needle.charAt(j)) {
                j = next[j - 1]; // 有冲突回到前一位,然后对比那个所对应的下标为j的字符对不对得到
            }
            if (needle.charAt(i) == needle.charAt(j)) {
            	//对得到加上1
                j++;
            }
            next[i] = j;
        }


这个代码其实不是好理解直接看的话,其实他这里是因为有一种规律在里面,假设我们现在next数组已经求好了。
他表示的含义呢我们前面也说了,表示的是这样的关系:
在这里插入图片描述

这个的话就是next数组里面不太好理解的地方,就是他是变求这个东西,边用这个东西。然后从左到右的一个计算,所有前面的值都是有的,也就是说能到。

理解不了的话,就记住嘛,也很好记,对得到j++,对不上j=next[j-1]
追不到,换一个妹子接着追,一直追不到,那一定是代码写错了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/101670.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Prometheus+Grafana

K8S prometheusK8S1.Prometheus&#xff08;普罗米修斯&#xff09;2.Prometheus可以做什么3.Prometheus的特点4.prometheus 相关组件二、prometheus与zabbix的区别zabbix架构区别三、prometheus架构分析1.TSDB2.时间序列数据库的特点3.prometheus 相关组件1.prometheus 核心组…

【计算机网络】实验五 网络层与链路层协议分析(PacketTracer)

一、实验目的 通过本实验&#xff0c;进一步熟悉PacketTracer的使用&#xff0c;学习路由器与交换机的基本配置&#xff0c;加深对网络层与链路层协议的理解。 二、实验内容&#xff1a; 4.1 路由器交换机的基本配置 打开下面的实验文件&#xff0c;按提示完成实验。 4.2…

直流微电网中潮流(Matlab代码实现)

目录 1 概述 1.1 直流电网中的潮流 1.2 创新点和相关工作 1.3 本文结构 2 数学/网络模型 2.1 主-从操作 2.2 孤岛运行 3 牛顿法 4 案例及Matlab代码实现 1 概述 潮流是一个非线性问题&#xff0c;需要用牛顿法求解具有恒定功率端子的直流微电网。本文提出了牛顿法在…

曙光来临!Nature终于发现了新冠特效药?或将彻底终结新冠时代!

百趣代谢组学文献分享&#xff1a;2022年即将过去&#xff0c;随着疫苗的全面接种和三年以来“动态清零”的坚持&#xff0c;我们在应对新冠病毒如潮水般的攻击中取得了阶段性成果。虽然大家陆陆续续投入到正常的工作生活中&#xff0c;但是我们都知道新冠并未被“打败”&#…

MySQL中这14个有用的小知识,快学起来吧

前言 我最近用MYSQL数据库挺多的&#xff0c;发现了一些非常有用的小玩意&#xff0c;今天拿出来分享到大家&#xff0c;希望对你会有所帮助。 1.group_concat 在我们平常的工作中&#xff0c;使用group by进行分组的场景&#xff0c;是非常多的。 比如想统计出用户表中&…

如何在产品开发中讨论概念设计?

每当你看到一辆在路上行驶的汽车、书桌上的笔记本电脑、工业包装生产线、医院设备、家用仪器和其他形式的概念设计创意产品会感到难以置信&#xff0c;这就是我们在产品开发中讨论概念设计的原因。 概念设计是一个尚未解决或到目前为止尚未令人满意的问题。这是一个深思熟虑的解…

研究区域制图 | 在 ArcGIS Pro中创建地图布局

研究区域制图 | 在 ArcGIS Pro中创建地图布局 数据准备 首先需要两个图层&#xff0c;一个是市区图层&#xff0c;一个是省行政区划图层&#xff0c;我这里以吉林省以及吉林省长春市为例 新建布局 选择横向A5即可 添加参考线 不知道你们知不知道这个功能&#xff0c;反正小…

kotlin协程笔记:Dispatchers

Kotlin 的 launch 会调用 startCoroutineCancellable()&#xff0c;接着又会调用 createCoroutineUnintercepted()&#xff0c;最终会调用编译器帮我们生成 SuspendLambda 实现类当中的 create() 方法。 public fun CoroutineScope.launch(context: CoroutineContext EmptyC…

【JVM】本地方法栈与堆与方法区

文章目录1. 本地方法栈2. 堆3. 方法区1. 本地方法栈 本地方法栈和虚拟机栈有点类似&#xff0c;均具有线程隔离的特点以及都能抛出StackOverflowError和OutOfMemoryError异常。 但是不同之处在于本地方法栈服务的对象是JVM执行的native方法&#xff0c;而虚拟机栈服务的是JVM…

[附源码]Nodejs计算机毕业设计教师职称评定系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

免费提供POSMV的GNSS数据解算服务,验潮仪丢失的一种补救

前两天有个网友问干活的区域附近是否有长期验潮站&#xff0c;因为他的临时验潮仪丢失了&#xff0c;随后问了一下搞水文的同事&#xff0c;他推了一个网址&#xff1a; http://publictide.nmdis.org.cn/tide?SiteGroup3&TideType0&#xff0c;中文名叫&#xff1a;潮汐潮…

C型利钠肽 ,101135-67-5

Bz-VGR-pNA, chromogenic substrate for trypsin and for bacterial trypsin-like proteases.Bz-VGR-pNA&#xff0c;胰蛋白酶和细菌胰蛋白酶样蛋白酶的显色底物。 编号: 127015中文名称: C型利钠肽 (TYR0)-C-PEPTIDE (DOG)英文名: (Tyr0)-C-Peptide (dog)CAS号: 101135-67-5单…

机房动环监控系统3大价值,第一个太惊艳了

在中小学、大学院校中&#xff0c;机房已经是不可缺少的部分&#xff0c;但由于管理缺陷、设备复杂等缘故&#xff0c;学校机房得不到安全保障。 因此&#xff0c;要实现学校机房监控系统&#xff0c;来对机房的运行情况实时监测&#xff0c;以此提高风险预防及设备运行环境质量…

C++利用模板实现消息订阅和分发

解耦是编写程序所遵循的基本原则之一&#xff0c;多态是提高程序灵活性的重要方法。C语言支持重载&#xff0c;模板&#xff0c;虚函数等特性&#xff0c;为编写高性能可扩展的程序提供了利器。编写大型项目时&#xff0c;免不了需要各个模块之间相互调用&#xff0c;从而产生了…

【LeetCode题目详解】(四)20.有效的括号、225.用队列实现栈

目录 一、力扣第20题&#xff1a;有效的括号 1.解题思路 2.写出代码 3.完整代码 二、力扣第225题&#xff1a;用队列实现栈 1.思路分析 2.代码实现 3.完整代码 总结 一、力扣第20题&#xff1a;有效的括号 题目链接&#xff1a;20. 有效的括号 - 力扣&#xff08;Leetc…

计算机毕设Python+Vue学生寝室管理系统(程序+LW+部署)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

哈夫曼树的构造及应用

哈夫曼树的构造及应用 文章目录哈夫曼树的构造及应用带权路径长度哈夫曼树定义哈夫曼树的性质&#xff1a;构造哈夫曼树构造哈夫曼树存储及生成算法算法框架代码实操:应用: 哈夫曼编码带权路径长度 设二叉树具有n个带权值的叶子节点,那么从根节点到各个叶子节点的路径长度与相应…

【图像分割】模糊聚类算法FCM图像分割【含Matlab源码 084期】

⛄一、模糊聚类算法FCM简介 1 前言 图像分割是图像进行后续分析处理的基础&#xff0c;它将图像分成不同特征部分并获得所需目标&#xff0c;广泛应用于诸多领域&#xff0e;彩色多目标图像具有更为丰富的图像信息&#xff0c;目标色彩较多&#xff0c;且同一色彩的目标有时具…

统计学习方法 | 感知机

感知机是二类分类的线性分类模型&#xff0c;其输入为实例的特征向量&#xff0c;输出为实例的类别&#xff0c;取1和-1二值 感知机对应于输入空间&#xff08;特征空间&#xff09;中将实例划分为正负两类的分离超平面&#xff0c;属于判别模型 一.模型介绍和学习策略 1.模…

牛客题霸sql入门篇之多表查询

牛客题霸sql入门篇之多表查询 1 子查询 1.1 浙江大学用户题目回答情况 1.1.1 题目内容 a 内容1 b 内容2 1.1.2 示例代码 SELECT device_id,question_id,result FROM question_practice_detail WHERE device_id(SELECT device_id FROM user_profile WHERE university浙江大…