【数据结构与算法】力扣 459. 重复的子字符串

题目描述

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • 1 <= s.length <= 104
  • s 由小写英文字母组成

分析解答

重复的子串连接成父串?重复?repeat!重复的次数?父串的长度是子串的几倍就是重复几次!

/*** @param {string} s* @return {boolean}*/
var repeatedSubstringPattern = function (s) {let subStr = ''for (let i = 0; i < s.length - 1; i++) {subStr += s[i]if (s === subStr.repeat(Math.floor(s.length / subStr.length))) {return true}}return false
};

思路拓展

移动匹配

既然是由重复的子串构成的,那么该字符串的首尾子串一定是相等的。所以:首 + 中间部分 + 尾 => 原字符串,那么,以此类推,尾 + 中间部分 + 首 => 原字符串。

所以我们的思路是:将两个字符串拼起来,找这个二倍的字符串是否含有原字符串(去掉首尾,防止两个原字符串的干扰)。

var repeatedSubstringPattern = function (s) {let str = s + sstr = str.slice(1, str.length - 1)if (str.includes(s)) {return true}return false
};

KMP

next 数组是一个辅助数组,用来记录每个位置之前的最长相同前缀后缀的长度。通过计算next数组,就能得到字符串中最长的重复子串的长度。

主要逻辑如下:

  • 首先进行一些边界判断,如果字符串的长度为0,则返回false。
  • 然后定义了一个名为getNext的函数,用来计算next数组。这个函数通过使用双指针遍历字符串,根据不同的情况更新指针及next数组的值。具体来说:
    • 初始化一个next数组和一个指针j。
    • 将j的初始值0存入next数组中。
    • 从1到字符串的长度-1进行遍历,将指针j根据不同情况进行更新,并将更新后的j的值存入next数组中。
    • 最后返回next数组。
  • 接下来,调用getNext函数得到next数组。
  • 最后通过判断条件(最后位置的最长相同前后缀不能为 0 ;而且整个字符串的长度一定是最长相同前后缀的整数倍,也就是模为 0)来比较字符串长度是否是最长重复子串长度的倍数,如果是则返回true,否则返回false。

这段代码主要运用了KMP算法中的next数组计算来判断字符串是否由重复的子串组成。

/*** @param {string} s* @return {boolean}*/
var repeatedSubstringPattern = function (s) {if (s.length === 0) {return false}const getNext = (s) => {let next = []let j = 0next.push(j)for (let i = 1; i < s.length; i++) {while (j > 0 && s[i] !== s[j]) {j = next[j - 1]}if (s[i] === s[j]) {j++}next.push(j)}return next}let next = getNext(s)if (next[next.length - 1] !== 0 && s.length % (s.length - next[next.length - 1]) === 0) {return true}return false
};
let s = "aba"
console.log(repeatedSubstringPattern(s))

详细讲讲 getNext 这个方法:

当进行字符串匹配时,我们需要找到一个最长的相同前缀后缀。这个相同前缀后缀的长度决定了我们在匹配失败时应该回退多少位。

getNext方法就是用来计算这个最长的相同前缀后缀的长度。它使用了双指针的方法来遍历字符串s,并根据不同的情况更新指针和next数组的值。

具体的实现逻辑如下:

  1. 首先,我们先定义一个数组next用来存储最长相同前缀后缀的长度。
  2. 接着,我们定义两个指针i和j,初始值都为0。指针i表示当前要计算最长相同前缀后缀的后缀的末尾位置,指针j表示当前已经求得的最长相同前缀后缀的长度。
  3. 先将指针j的初始值0存入next数组的第一个位置。
  4. 从字符串s的第二个字符开始,即i从1到s.length-1,进行遍历。
  5. 在遍历过程中,我们通过比较s[i]和s[j]的值,来更新指针j和next数组的值。具体的操作如下:
    • 如果s[i]和s[j]相等,说明当前的字符可以加入到已知的最长相同前缀后缀中,所以我们将指针j加1,并将j的值存入next数组的当前位置。
    • 否则,我们需要寻找更短的相同前缀后缀,所以我们将指针j回退到前一个位置,通过next[j-1]来获取更短的相同前缀后缀的长度。我们将比较s[i]和s[j-1]的值,直到找到一个相等的字符或者j回退到0为止。
      • 如果j回退到0仍然没有找到相等的字符,说明当前位置不存在相同的前缀后缀,所以将指针i加1,并将j的值0存入next数组的当前位置。
      • 如果找到了一个相等的字符s[i]和s[j-1],说明我们找到了一个更短的相同前缀后缀,所以我们将指针j加1,并将j的值存入next数组的当前位置。
  6. 遍历结束后,我们可以得到一个完整的next数组,其中的每个值都代表了相应位置的最长相同前缀后缀的长度。

通过getNext方法计算得到的next数组,可以用于优化字符串匹配算法,如KMP算法等。在本段代码中,我们利用next数组的最后一个值,来判断字符串是否是由重复的子串组成的。

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

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

相关文章

WebGIS

文章目录 GIS的全名是Geographic Information System&#xff0c;中文全名是地理信息系统。 它是在计算机硬、软件系统支持下&#xff0c;对整个或部分地球表层&#xff08;包括大气层&#xff09;空间中的有关地理分布数据进行采集、储存、管理、运算、分析、显示和描述的技术…

详解23种设计模式——单例模式

单例模式 | CoderMast编程桅杆单例模式 单例模式是最常用的设计模式之一&#xff0c;他可以保证在整个应用中&#xff0c;某个类只存在一个实例化对象&#xff0c;即全局使用到该类的只有一个对象&#xff0c;这种模式在需要限制某些类的实例数量时非常有用&#xff0c;通常全局…

【GitHub】如何在github上提交PR(Pull Request) + 多个pr同时提交、互不干扰

【GitHub】如何在github上提交PR(Pull Request 写在最前面1. 准备工作1.1 注册 GitHub 账号1.2 了解 Git 基础1.3 找到一个项目 2. 创建你的 PR2.1 Fork 和克隆仓库2.2 创建一个新的分支2.3 进行更改2.4 推送更改到 GitHub2.5 创建 Pull Request 3. 优化你的 PR3.1 保持提交清晰…

基于VMD-CNN-BiLSTM-Attention组合模型时间序列预测

VMD-CNN-BiLSTM-Attention组合模型是一种复杂的神经网络结构&#xff0c;用于时间序列预测。让我逐步解释这个模型的每个组成部分以及它们是如何结合在一起的&#xff1a; VMD&#xff08;Variational Mode Decomposition&#xff09;&#xff1a;VMD是一种信号处理技术&#x…

Python、Django和MySQL框架的开源项目中值得学习和借鉴的项目

在Python、Django和MySQL框架的开源项目中&#xff0c;有很多值得学习和借鉴的项目。这些项目不仅可以帮助你了解如何使用这些技术栈进行开发&#xff0c;还能为你提供实践经验和灵感。以下是一些基于PythonDjangoMySQL框架的开源项目示例&#xff1a; Django博客系统&#xff…

【MySQL】DML

1、DML简介 DML&#xff08;Data Manipulation Language、数据操作语言&#xff09;&#xff0c;用于添加、删除、更新和查询数据库记录&#xff0c;并检查数据完整性。 2. 添加数据 2.1 使用关键字 使用 INSERT 语句向表中插入数据。使用 VALUES语句添加 2.2 使用情况 2.2…

JetBot手势识别实验

实验简介 本实验目的在JetBot智能小车实现手势识别功能&#xff0c;使用板卡为Jetson Nano。通过小车摄像头&#xff0c;识别五个不同的手势&#xff0c;实现小车的运动及灯光控制。 1.数据采集 连接小车板卡的Jupyterlab环境&#xff0c;运行以下代码块&#xff0c;配置数据…

Vitis HLS 学习笔记--C/C++ static 关键字的作用

目录 1. 简介 2. c/c共有性质 3. c独有性质 4. 示例说明 5. static 对于 HLS 工具的影响 6. 总结 1. 简介 在Vitis HLS中&#xff0c;偶尔会用到 static 关键字。考虑到Vitis HLS同时兼容C和C语言&#xff0c;有必要理解这两种语言中static关键字细微差异。本文旨在梳理…

靠近特定对象才可使用法术

实现目标 只有靠近特定creature | gameobject 才能使用特定技能&#xff0c;否则技能无法使用 实现方法 conditions SourceTypeOrReferenceId&#xff1a;17&#xff08;CONDITION_SOURCE_TYPE_SPELL&#xff09;SourceGroup&#xff1a;0SourceEntry&#xff1a;技能ID&am…

Linux cmake 初窥【1】

1.开发背景 linux 下编译程序需要用到对应的 Makefile&#xff0c;用于编译应用程序&#xff0c;但是 Makefile 的语法过于繁杂&#xff0c;甚至有些反人类&#xff0c;所以这里引用了cmake&#xff0c;cmake 其中一个主要功能就是用于生成 Makefile&#xff0c;cmake 的语法更…

常见的css面试题(持续更新,欢迎补充)

目录 1. 什么情况下设置margin会造成margin塌陷? 怎么解决&#xff1f; 2. css的选择器的优先级&#xff0c;怎么判断谁的优先级更高&#xff1f; 总结面试常问的css相关面试题~ 1. 什么情况下设置margin会造成margin塌陷? 怎么解决&#xff1f; 通常遇见margin塌陷&…

AIGC:开启内容创作新纪元,我们如何看待它的影响与前景?

AIGC的概念 AIGC&#xff08;Artificial Intelligence Generated Content&#xff09;的概念主要是指人工智能生成内容。 这是一种新的人工智能技术&#xff0c;它利用人工智能模型&#xff0c;根据给定的主题、关键词、格式、风格等条件&#xff0c;自动生成各种类型的文本、图…

Maya vs Blender:制作3D动画首选哪一个?

就 3D 动画而言&#xff0c;有两款3D软件引发了最多的争论&#xff1a;Blender 与 Maya。这两个强大的平台都提供强大的工具集&#xff0c;使动画故事和角色栩栩如生。但作为一名3D动画师&#xff0c;您应该投入时间学习和创作哪一个呢&#xff1f;下面我将从以下六点给您一个清…

SQL优化——全自动SQL审核

文章目录 1、抓出外键没创建索引的表2、抓出需要收集直方图的列3、抓出必须创建索引的列4、抓出SELECT * 的SQL5、抓出有标量子查询的SQL6、抓出带有自定义函数的SQL7、抓出表被多次反复调用SQL8、抓出走了FILTER的SQL9、抓出返回行数较多的嵌套循环SQL10、抓出NL被驱动表走了全…

数据输出(进制、小数位,左对齐右对齐

#include <stdio.h> int main() {int a041; printf("%d\n",a);//33printf("%o\n",a);//41 %o输出八进制&#xff0c;开头不加0printf("%x\n",a);//21 %x输出十六进制&#xff0c;开头不加0Xprintf("%#o\n",a);//…

React学习day01--虚拟DOM的两种创建方式

一、使用js的方式创建虚拟DOM 使用js这种创建虚拟DOM的方式相对jsx来说是繁琐的&#xff0c;如果标签是深层次嵌套&#xff0c;那么书写非常耗时且麻烦。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta …

32个centos常见的命令使用

CentOS 是一个基于 Red Hat Enterprise Linux (RHEL) 的免费企业级操作系统。以下是一些基本的 CentOS 命令&#xff0c;用于日常管理和操作&#xff1a; 这些命令是Linux系统中常用的命令行工具&#xff0c;用于执行各种系统管理任务。下面是对每个命令的详细介绍&#xff0c…

关于豆瓣电影数据抓取以及可视化

首先我们可以先了解以下网络爬虫的定义&#xff1a; 爬虫是一种按照一定的规则&#xff0c;自动地抓取万维网信息的程序或者脚本。它可以在互联网上自动抓取网页内容&#xff0c;将这些信息存储起来。爬虫可以抓取网站的所有网页&#xff0c;从而获取对于我们有价值的信…

企业战略落地:单项目无法解决的,交给项目组合管理

在快速变化的市场环境中&#xff0c;企业对项目管理的需求日益增加&#xff0c;但传统的单项目管理和项目集管理难以满足企业对项目管理的更高要求。随后&#xff0c;项目组合管理方法论逐渐被越来越多的企业运用&#xff0c;并用于指导企业在复杂多变的经营环境下&#xff0c;…

工厂方法模式(模拟发奖多种商品)

目录 定义 模拟发奖多种商品 优惠券 实物商品 第三⽅爱奇艺兑换卡 代码实现 定义发奖接⼝ 实现奖品发放接⼝ 优惠券 实物商品 第三⽅兑换卡 创建商店⼯⼚ 测试验证 定义 在⽗类中提供⼀个创建对象的⽅法&#xff0c; 允许⼦类决定实例化对象的类型。 模拟发奖多…