重复的子字符串 | LeetCode-459 | 字符串匹配 | KMP | 双指针

news2024/11/24 12:34:06
🙋大家好!我是毛毛张!
🌈个人首页: 神马都会亿点点的毛毛张
🕹️KMP练习题

📌LeetCode链接:459. 重复的子字符串

文章目录

  • 1.题目描述🍍
  • 2.题解🫐
    • 2.1 暴力解法🍅
    • 2.2 KMP - 移动匹配🥭
      • 2.2.1 内置函数🎃
      • 2.2.2 KMP实现🍇
    • 2.3 KMP优化🍒
  • 3.相关练习🍑

1.题目描述🍍

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

示例 1:

输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。

示例 2:

输入: s = "aba"
输出: false

示例 3:

输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)

提示:

  • 1 < = s . l e n g t h < = 1 0 4 1 <= s.length <= 10^4 1<=s.length<=104
  • s 由小写英文字母组成

2.题解🫐

2.1 暴力解法🍅

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        int n = s.length();  // 获取字符串的长度
        // 枚举可能的子串长度,最大长度为字符串长度的一半
        for(int i = 1; i <= n / 2; i++) {
            // 如果字符串长度能被子串长度整除,说明可能由该长度的子串重复构成
            if(n % i == 0) {
                int j;
                // 检查从索引 i 开始的字符是否和子串的字符匹配
                for(j = i; j < n; j++) {
                    // 如果当前字符与前面子串对应位置的字符不匹配,跳出循环
                    if(s.charAt(j) != s.charAt(j - i)) break;
                }
                // 如果 j 遍历到了字符串的末尾,说明整个字符串可以由子串重复构成
                if(j == n) return true;
            }
        }
        // 如果没有找到满足条件的子串,返回 false
        return false;
    }
}

2.2 KMP - 移动匹配🥭

2.2.1 内置函数🎃

class Solution {
    // 判断字符串 s 是否由一个子串重复组成
    public boolean repeatedSubstringPattern(String s) {
        // 将字符串 s 自身连接,并从索引 1 开始查找 s 的首次出现位置
        // 如果找到了且位置不等于 s 的长度,说明 s 是由一个子串重复组成
        return (s + s).indexOf(s, 1) != s.length();
    }
}

2.2.2 KMP实现🍇

class Solution {
    // 判断字符串 s 是否由一个子串重复组成
    public boolean repeatedSubstringPattern(String s) {
        int n = s.length(); // 获取字符串 s 的长度
        String goal = s; // 保存原始字符串
        s = s + s; // 将字符串 s 自身连接,形成新的字符串
        int[] next = getNext(goal); // 生成目标字符串的前缀函数数组
        int j = 0; // 初始化匹配指针,用于遍历目标字符串

        // 遍历新的字符串 s,直到 n*2-1 位置
        for (int i = 1; i < n * 2 - 1; i++) {
            // 当前字符不匹配时,根据前缀函数回退 j
            while (j > 0 && s.charAt(i) != goal.charAt(j)) j = next[j - 1];
            // 如果字符匹配,增加 j
            if (s.charAt(i) == goal.charAt(j)) j++;
            // 如果 j 达到目标字符串的长度,表示找到了重复子串
            if (j == n) return true;
        }

        return false; // 如果没有找到符合条件的重复子串,返回 false
    }
    // 生成前缀函数数组
    public int[] getNext(String s) {
        int n = s.length(); // 获取字符串 s 的长度
        int[] next = new int[n]; // 初始化前缀函数数组
        int j = 0; // 前缀指针
        next[0] = 0; // 第一个字符的前缀长度为 0

        // 遍历字符串,从第二个字符开始
        for (int i = 1; i < n; i++) {
            while (j > 0 && s.charAt(i) != s.charAt(j)) j = next[j - 1];// 当当前字符不匹配时,回退前缀指针 j
            if (s.charAt(i) == s.charAt(j)) j++;// 如果字符匹配,前缀长度增加
            next[i] = j;// 记录当前字符的前缀长度到 next 数组
        }
        
        return next; // 返回前缀函数数组
    }
}

2.3 KMP优化🍒

  • 这个方法需要对种字符串的next数组的特征要了解,毛毛张在下面举几个例子
    • 正例: 字符串ababababnext数组:[0, 0, 1, 2, 3, 4, 5, 6]
    • 正例: 字符串ababcababcababcnext数组:[0, 0, 1, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    • 反例: 字符串abcabcanext数组:[0, 0, 0, 1, 2, 3, 4]
class Solution {
    public boolean repeatedSubstringPattern(String s) {
        int n = s.length(); // 获取字符串 s 的长度
        int[] next = getNext(s); // 生成字符串 s 的前缀函数数组
        int minLen = n - next[n - 1]; // 计算最小重复子串的长度
		//minLen < n 是为了防止这种情况:abcdef 此时minLen=0 
        // 如果最小长度小于字符串长度,并且字符串长度能够被最小长度整除,则存在重复子串
        if (minLen < n && n % minLen == 0) return true;
        
        return false; // 否则返回 false
    }

    // 生成前缀函数数组
    public int[] getNext(String s) {
        int n = s.length(); // 获取字符串 s 的长度
        int[] next = new int[n]; // 初始化前缀函数数组
        int j = 0; // 前缀指针
        next[0] = 0; // 第一个字符的前缀长度为 0

        // 遍历字符串,从第二个字符开始
        for (int i = 1; i < n; i++) {
            while (j > 0 && s.charAt(i) != s.charAt(j)) j = next[j - 1];// 当当前字符不匹配时,回退前缀指针 j
            if (s.charAt(i) == s.charAt(j)) j++;// 如果字符匹配,前缀长度增加
            next[i] = j;// 记录当前字符的前缀长度到 next 数组
        }
        
        return next; // 返回前缀函数数组
    }
}

3.相关练习🍑

  • 找出字符串中第一个匹配项的下标 | LeetCode-28 | KMP算法 | next数组 | Java详细注释
  • 旋转字符串 | LeetCode-796 | 模拟 | KMP | 字符串匹配

都看到这了,不妨一键三连再走吧!

🌈欢迎和毛毛张一起探讨和交流!
联系方式参见个人主页:
神马都会亿点点的毛毛张

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

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

相关文章

enhanced Input Action IA_Look中Action value引脚没有分割结构体引脚的选项

UE5系列文章目录 文章目录 UE5系列文章目录前言二、使用步骤解决办法 前言 据说&#xff0c;unreal engine5中准备废弃“项目设置”中“输入”&#xff0c;操作映射&#xff0c;轴映射。取而代之的是&#xff1a; 使用增强的输入动作&#xff08;Enhanced Input Actions&#…

【QT】Qt SDK的下载,安装和环境配置

目录 一&#xff0c;Qt SDK的下载二&#xff0c;Qt SDK的安装三&#xff0c;验证Qt SDK安装是否成功四&#xff0c;Qt环境变量配置 一&#xff0c;Qt SDK的下载 进入下面两个网站都可以进行下载&#xff1a; Qt 下载官⽹ 国内清华源 进⼊官⽹&#xff0c;按如下图⽰进⾏相应…

Allegro如何导入DXF结构文件并生成板框(1)?

在用Allegro进行PCB设计时,需要导入DXF结构文件,由此来生成PCB的板框。 本节先讲Allegro如何导入DXF结构文件?下节讲如何利用导入的DXF结构文件生成OUTLINE板框。 Allegro如何导入DXF结构文件并生成板框(2)?-CSDN博客 详细操作方法如下: 1、选择菜单栏File 选择Import…

【EI会议】第三届环境工程与可持续能源国际会议征稿开启

第三届环境工程与可持续能源国际会议&#xff08;EESE 2024&#xff09;将于2024年12月20日至21日在湖南长沙召开&#xff0c;诚挚邀请相关领域学者、专家加入会议&#xff0c;开展学术讨论和研究&#xff0c;共同助推环境工程与可持续能源产学研领域的进步&#xff01; 征稿主…

SDK does not contain ‘libarclite‘ at the path

Xcode15运行报错:SDK does not contain libarclite at the path /Applications/Xcode.app/Contents/ Developer/Toolchains/XcodeDefault.xctoolchain/us/lib/arc/libarclite_iphoneos.a 如下图: 阅读报错信息,它的意思是 SDK没有包含 libarclite 这个文件,这个文件的路径是: …

基于 face_recognition 的人脸识别的小工具

使用 face_recognition 和 pyside2&#xff0c;开发了一个小工具&#xff0c;识别指定的人脸照片&#xff0c;保存到指定的文件夹。 源码如下&#xff1a; import sys import os import shutil import face_recognition import logging from PySide2.QtWidgets import QApplic…

PDF文件转换为HTML文件

推荐使用 pdf2htmlEX&#xff08;因为确实做的比较全&#xff09; pdf2htmlEX 是一个开源工具&#xff0c;可以将PDF文件转换为HTML文件。你需要先安装pdf2htmlEX工具&#xff0c;并确保它在你的系统路径中可用。&#xff08;花时间最多就是找包&#xff09; 安装 pdf2htmlEX …

API以及添加学生信息练习

API:应用程序编程接口 简单理解&#xff1a;API就是别人已经写好的东西&#xff0c;我们不需要自己编写&#xff0c;直接使用即可 Java API&#xff1a;指的就是jdk中提供的各种功能的Java类&#xff0c;这些类将底层的实现封装起来&#xff0c;我们不需关心这些类是如何实现的…

什么是神中神公司?发表内卷言论,分分钟要你道歉...

谷歌 海的那边&#xff0c;这几天最乐的新闻&#xff0c;是谷歌前 CEO 批评员工不拼命工作后道歉。 今年 4 月&#xff0c;谷歌前 CEO 埃里克施密特&#xff08;Eric Schmidt&#xff09;在斯坦福大学的一次演讲中&#xff0c;被问及 OpenAI 和 Anthropic 等初创公司目前在人工…

【全面解析】芯片采购渠道策略:原厂直采VS代理VS现货市场

芯片作为现代科技的基石&#xff0c;其重要性不言而喻。无论是智能手机、汽车电子、物联网设备还是高性能计算领域&#xff0c;都离不开芯片的支持。随着5G、AI、大数据等前沿技术的飞速发展&#xff0c;对芯片的需求量持续攀升&#xff0c;如何确保稳定、高效的芯片供应链成为…

A3VLM: Actionable Articulation-Aware Vision Language Model

发表时间&#xff1a;13 Jun 2024 作者单位&#xff1a;SJTU Motivation&#xff1a;以往的机器人VLM如RT-1[4]、RT-2[3]和ManipLLM[21]都专注于直接学习以机器人为中心的动作。这种方法需要收集大量的机器人交互数据&#xff0c;这在现实世界中非常昂贵。 解决方法&#xf…

数据中台之数据开发-离线开发和实时开发

目录 一、离线开发 1.1 概述 1.2 作业调度 1.3 基线控制 1.4 异构存储 1.5 代码校验 1.6 多环境级联 1.7 推荐依赖 1.8 数据权限 二、实时开发 2.1 概述 2.2 实时计算的特点 2.2.1 实时且无界(unbounded)的数据流 2.2.2 持续且高效的计算 2.2.3 流式且实时的数据…

go,gin封装gorm使用,增删改查

1、主 package mainimport ("fmt""wbGo/configs" )type Dades struct {Id intName stringAge int }func main() {//连接数据库configs.BaseName("wbrj_sample")var data []Dades//查询configs.Db.Raw("select * from dade where id>…

机器学习/深度学习——关于分类任务的机器学习、深度学习模型的评估指标详解

机器学习/深度学习——模型的评估详解 搭配以下文章进行学习&#xff1a; 卷积神经网络&#xff1a; 深度学习——卷积神经网络&#xff08;convolutional neural network&#xff09;CNN详解&#xff08;一&#xff09;——概述. 步骤清晰0基础可看 深度学习——卷积神经网…

Ciallo~(∠・ω・ )⌒☆第十七篇 Ubuntu基础使用 其一

Ubuntu是一种基于Linux的操作系统&#xff0c;它是开源的、免费的&#xff0c;并且具有广泛的用户群体。 基本文件操作&#xff1a;Ubuntu使用命令行工具来进行文件操作。以下是一些常用的命令&#xff1a; 切换到用户主目录&#xff1a; cd ~ 切换到上级目录&#xff1a; cd .…

QT 数据导出到Excel

原创&#xff1a;QT 数据导出到Excel 在Qt自带的axcontainer模块中&#xff0c;我们可以使用QAxObject类来将数据保存到Excel中。Qt中将数据保存到Excel通常有两种方式&#xff1a;一种是以Excel格式导出&#xff0c;需要电脑上安装Office软件&#xff1b;另一种是以CSV格式导出…

用户端是小程序,后台管理系统是PC端的CMS系统

1. 数据库表设计 1.1 课程轮播图表 CREATE TABLE course_banners (id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 轮播图主键,image_url varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 轮播图图片链接,title varchar(255) CHARAC…

高考志愿智能推荐系统-计算机毕设Java|springboot实战项目

&#x1f34a;作者&#xff1a;计算机毕设残哥 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目、 源…

Lesson 64 Don‘t ... You mustn‘t ...

Lesson 64 Don’t … You mustn’t … 词汇 play n. 戏剧&#xff08;真人演的&#xff0c;话剧&#xff09;v. 玩耍 搭配&#xff1a;play with 物体 / 人    玩…… / 和……一起玩 例句&#xff1a;我正在和Leo玩。    I am playing with Leo.演奏&#xff08;乐器…

代码随想录算法训练营第十六天

力扣题部分: 513.找树左下角的值 题目链接:. - 力扣&#xff08;LeetCode&#xff09; 题面: 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 思路(层序遍历): 应该是这道题最简单的方法了&#xff0…