算法打卡day8|字符串篇02|Leetcode 28. 找出字符串中第一个匹配项的下标、459. 重复的子字符串

 算法题

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

题目链接:28. 找出字符串中第一个匹配项的下标

大佬视频讲解:KMP理论篇

KMP代码篇

个人思路

当看到在一个串中查找是否出现过另一个串,那肯定是用kmp算法了; kmp比较难理解,详细理论和代码可以看上面视频参考;

按照个人理解 kmp就是帮忙在 查找串时减少不必要的检索;

用一个叫做前缀表(next)的数组先来找到 最长相等前后缀的位置, 然后 双指针检索 目标字符串,在源字符串 字母与目标字符串字母相同 时,往前走,不同时找前缀表对应位置回退;

解法
KMP算法

n为目标串长度,m为源串长度,因为在匹配的过程中,根据前缀表不断调整匹配的位置,可以看出匹配的过程是O(n),之前还要单独生成next数组,时间复杂度是O(m)。所以整个KMP算法的时间复杂度是O(n+m)的。而暴力的解法显而易见是O(n × m),所以KMP在字符串匹配中极大地提高了搜索的效率。

其中前缀表有多种方式生成,这里采用 不减一的情况.

class Solution {public int strStr(String haystack, String needle) {if (needle.length() == 0) return 0;int[] next = new int[needle.length()];getNext(next, needle);//用源串needle 生成前缀表int j = 0;for (int i = 0; i < haystack.length(); i++) {//遍历目标串while (j > 0 && needle.charAt(j) != haystack.charAt(i)) //字符不同时,按照前缀表回退 即从next数组里寻找下一个匹配的位置j = next[j - 1];if (needle.charAt(j) == haystack.charAt(i)) j++;//字符相同,那么i 和 j 同时向后移动//如果j指向了模式串t的末尾,那么就说明源串完全匹配目标串里的某个子串了if (j == needle.length()) return i - needle.length() + 1;//返回第一个匹配到串的位置}return -1;}//前缀表(不减一)private void getNext(int[] next, String s) {int j = 0;next[0] = 0;for (int i = 1; i < s.length(); i++) {//i从1开始才能与j开始对比while (j > 0 && s.charAt(j) != s.charAt(i)) // 前后缀不相同时j = next[j - 1];// 向前回退if (s.charAt(j) == s.charAt(i)) // 找到相同的前后缀j++;next[i] = j; // 将j(前缀的长度)赋给next[i]}}
}

时间复杂度:O(n+m);(双指针遍历字符串全部)

空间复杂度:O(m);(只需要保存字符串needle的前缀表)

Leetcode 459. 重复的子字符串

题目链接:459. 重复的子字符串

大佬视频讲解:459. 重复的子字符串

个人思路

思路不清晰

解法

移动匹配

题目难度主要在于如何分辨字符串是否能由子串重复构成;

当一个字符串s:godgod,内部由重复的子串组成,那么这个字符串的结构一定是这样的:

s是由前后相同的子串组成。那么既然前面有相同的子串,后面有相同的子串,用 s + s,这样组成的字符串中,后面的子串做前串,前面的子串做后串,就一定还能组成一个s,如图:

所以判断字符串s是否由重复子串组成,只要两个s拼接在一起,刨除 s + s 的首字符和尾字符(避免在s+s中搜索出原来的s), 里面还出现一个s的话,就说明是由重复子串组成.

class Solution {public boolean repeatedSubstringPattern(String s) {
//indexOf(s, 1)查找字符串 s 第一次出现的位置,从索引1开始搜索(即从原字符串的第二个字符开始搜索)return (s + s).indexOf(s, 1) != s.length();}
}

时间复杂度:O(n);(查找索引)

空间复杂度:O(1);(没使用辅助空间)

KMP算法

在一个串中查找是否出现过另一个串,这是KMP的看家本领;

先放结论, 数组长度减去最长相同前后缀的长度相当于是第一个周期的长度,也就是一个周期的长度,如果这个周期可以被整除,就说明整个数组就是这个周期的循环。

这样直接说有点抽象,举个例子:

next[len - 1] = 8,8就是此时字符串goodgoodgoodgood的最长相同前后缀的长度。(前缀不包括最后一个字符,后缀不包括第一个字符)

(len - (next[len - 1] )) 也就是: 12(字符串的长度) - 8(最长公共前后缀的长度) = 4, 4正好可以被 12(字符串的长度) 整除,所以说明有重复的子字符串(good)

class Solution {public boolean repeatedSubstringPattern(String s) {if (s.equals("")) return false;int len = s.length();// 原串加个空格(哨兵),使下标从1开始,这样j从0开始,也不用初始化了s = " " + s;char[] chars = s.toCharArray();//字符串转换为字符数组int[] next = new int[len + 1];//前缀表// 构造 next 数组过程,j从0开始(空格),i从2开始for (int i = 2, j = 0; i <= len; i++) {// 匹配不成功,j回到前一位置 next 数组所对应的值while (j > 0 && chars[i] != chars[j + 1]) j = next[j];// 匹配成功,j往后移if (chars[i] == chars[j + 1]) j++;// 更新 next 数组的值next[i] = j;}// 判断是否是重复的子字符串if (next[len] > 0 && len % (len - next[len]) == 0) {return true;}return false;}
}

时间复杂度:O(n);(一个for循环)

空间复杂度:O(n);(next数组)

以上是个人的思考反思与总结,若只想根据系列题刷,参考卡哥的网址代码随想录算法官网

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

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

相关文章

c语言大小字母转换程序

#include <stdio.h> #include <ctype.h> // 引入ctype.h库以使用toupper和tolower函数 int main() { char str[100]; int choice; printf("Enter a string: "); fgets(str, sizeof(str), stdin); // 使用fgets读取字符串&#xff0c;包括空格 pr…

【Linux】入门篇---xshell安装以及远程连接Linux(看这篇就行啦!)

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

Java的单例模式

谦逊不值得可耻&#xff0c;放荡才是。 Humility is not worthy of shame, debauchery is. Java单例模式 单例模式是一种常见的设计模式&#xff0c;用于确保某个类只有一个实例&#xff0c;并提供一个全局访问点。 懒汉模式 vs 饿汉模式 懒汉模式 懒汉模式&#xff1a;在需…

GaussDB(DWS)运维利刃:TopSQL工具解析

在生产环境中&#xff0c;难免会面临查询语句出现异常中断、阻塞时间长等突发问题&#xff0c;如果没能及时记录信息&#xff0c;事后就需要投入更多的人力及时间成本进行问题的定位和解决&#xff0c;有时还无法定位到错误出现的地方。在本期《GaussDB(DWS)运维利刃&#xff1…

【Vue3】什么是路由?Vue中的路由基本切换~

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

Docker安装步骤笔记

一、环境准备 VM网络配置 打开VMware软件 --编辑 --虚拟网络编辑器 二、VM创建虚拟机 三、安装rhel8.9操作系统 1、rhel8.9 镜像下载 第一步&#xff1a;进入redhat官网进行注册第二步&#xff1a;下载rhel8.9镜像文件 https://access.redhat.com/downloads/content/rhel …

北京某中厂凉经

3月12号 大二想着找一份暑假面试&#xff0c;然后就海投。北京某上市公司给了面试&#xff0c;这也是我的第一个面试&#xff0c;听面试官最后的话大概是挂了。 大概回忆一下当时面试的部分内容吧&#xff0c;虽然已经过去一两小时的&#xff0c;而且我属于那种一面完就忘的差…

Vue3选项式api和组合式api

Vue3选项式api和组合式api 1、选项 Option API2&#xff0e;组合 Compsition API .3、关系&#xff1a; 1、选项 Option API 什么是选顶 API &#xff1a; 在vue2x项目中使用&#xff08; data , methods . computed ,watch &#xff09;中定义属性和方法就是选项 API 写法。 …

Slim-Neck by GSConv

paper&#xff1a;Slim-neck by GSConv: A better design paradigm of detector architectures for autonomous vehicles official implementation&#xff1a;https://github.com/alanli1997/slim-neck-by-gsconv 背景 目标检测是计算机视觉中一个重要的下游任务。对于车载…

神经网络线性量化方法简介

可点此跳转看全篇 目录 神经网络量化量化的必要性量化方法简介线性对称量化线性非对称量化方法神经网络量化 量化的必要性 NetworkModel size (MB)GFLOPSAlexNet2330.7VGG-1652815.5VGG-1954819.6ResNet-50983.9ResNet-1011707.6ResNet-15223011.3GoogleNet271.6InceptionV38…

Singularity(五)| 容器挂载和环境

Singularity&#xff08;五&#xff09;| 容器挂载和环境 我们可以按照如下方式运行 Singularity 容器&#xff1a; singularity shell samtoolssingularity exec samtools samtools helpsingularity run samtoolssingularity exec instance://samtools 在我们逐个详解容器运行…

【智能算法】哈里斯鹰算法(HHO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.代码实现4.参考文献 1.背景 2019年&#xff0c;Heidari 等人受到哈里斯鹰捕食行为启发&#xff0c;提出了哈里斯鹰算法(Harris Hawk Optimization, HHO)。 2.算法原理 2.1算法思想 根据哈里斯鹰特性&#xff0c;HHO分为探索-…

了解关键的区别并选择最好的

随着全球企业转向云管理数据库&#xff0c;数据库管理的世界已经发生了巨大的变化。然而&#xff0c;满足现代世界的需求可能具有挑战性&#xff0c;特别是对于内部部署。相比之下&#xff0c;托管云数据库是为云构建的可伸缩的关系数据库服务。Amazon AWS和Microsoft Azure是部…

【Android】 ClassLoader 知识点提炼

1.Java中的 ClassLoader 1.1 、ClassLoader的类型 Java 中的类加载器主要有两种类型&#xff0c;即系统类加载器和自定义类加载器。其中系统类 加载器包括3种&#xff0c;分别是 Bootstrap ClassLoader、Extensions ClassLoader 和 Application ClassLoader。 1.1.1.Bootstra…

图像超分辨率算法ESRGAN原理及应用

前言 图像超分辨率算法是一种用于增加图像分辨率的算法,与传统的图像缩放算法不同的是,超分算法在放大图像的同时根据原图纹理生成更多细节,确保图像在放大后仍然有清晰的纹理细节。 一、模型简介 1、模型开源地址 GitHub - xinntao/ESRGAN: ECCV18 Workshops - Enhance…

leetcode2834--找出美丽数组的最小和

1. 题意 求一个序列和。序列 a a a满足&#xff1a; 大小为 n n n ∀ 0 ≤ i , j < n , i ≠ j , a i a j ≠ t a r g e t \forall 0\le i,j \lt n,i \ne j,a_ia_j \ne target ∀0≤i,j<n,ij,ai​aj​target 找出美丽数组的最小和 2. 题解 贪心的构造这个序列。…

鸿蒙原生应用元服务开发-WebGL网页图形库开发无着色器绘制2D图形

无着色器绘制2D图形 使用WebGL开发时&#xff0c;为保证界面图形显示效果&#xff0c;请使用真机运行。 此场景为未使用WebGL绘制的2D图形&#xff08;CPU绘制非GPU绘制&#xff09;。开发示例如下&#xff1a; 1.创建页面布局。index.hml示例如下&#xff1a; <div class…

算法学习---栈和队列算法学习

一、用栈去实现队列 1.整理思路 栈的特点&#xff1a;先进后出 队列的特点&#xff1a;先进先出 我们要用栈的先进后出&#xff0c;来模拟实现队列的先进后出。我们需要借助两个栈去实现&#xff0c;分别叫做栈1和栈2。 栈1主要是用来存储数据的&#xff0c;我们将要插入的数据…

树莓派Python环境配置:删除Python 2、默认使用Python 3及配置Python镜像源指南

树莓派Python环境配置&#xff1a;优化升级三部曲 文章目录 树莓派Python环境配置&#xff1a;优化升级三部曲前言一、查看系统预装的python版本二、卸载python2并默认python3三、删除默认python3.7并升级到python3.9四、更换树莓派上的pip系统镜像源一键更换清华源&#xff08…

LoadRunner学习:RuntimeSetting、参数化、关联、(unfinished

LoadRunner RuntimeSetting 运行时设置 在Vuser中设置Run-time Settings RunLogic&#xff1a;运行逻辑&#xff0c;决定了脚本真正执行逻辑&#xff0c; Init和End部分代码只能执行一次。决定脚本真正执行逻辑的意思是&#xff0c;在Run中的代码和Number of Iteration决定了…