LeetCode 466. 统计重复个数,循环字符串匹配优化

2024-01-03 15:04

本文主要是介绍LeetCode 466. 统计重复个数,循环字符串匹配优化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、题目

1、题目描述

定义 str = [s, n] 表示 str 由 n 个字符串 s 连接构成。

  • 例如,str == ["abc", 3] =="abcabcabc" 。

如果可以从 s2 中删除某些字符使其变为 s1,则称字符串 s1 可以从字符串 s2 获得。

  • 例如,根据定义,s1 = "abc" 可以从 s2 = "abdbec" 获得,仅需要删除加粗且用斜体标识的字符。

现在给你两个字符串 s1 和 s2 和两个整数 n1 和 n2 。由此构造得到两个字符串,其中 str1 = [s1, n1]str2 = [s2, n2] 。

请你找出一个最大整数 m ,以满足 str = [str2, m] 可以从 str1 获得。

2、接口描述

class Solution {
public:int getMaxRepetitions(string s1, int n1, string s2, int n2) {}
};

3、原题链接

466. 统计重复个数


二、解题报告

1、思路分析

官方给出的解法是循环节解法,笔者采用了类似KMP优化字符串匹配的思想,不难想到我们只要计算出n1个s1中匹配的s2的数量然后除以n2就是答案,那么我们无非就是在s1 * n1这个字符串上进行了一次字符串匹配,我们暴力的求解,即从第0个字符一直到len1 * n1个字符进行和s2的匹配,记录s2的数目则有如下暴力代码:

class Solution {
public:Solution(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);}int getMaxRepetitions(string s1, int n1, string s2, int n2) {int len1 = s1.size() , len2 = s2.size() , p2 = 0 , cnt = 0;for(int i = 0 ; i < n1 ; i++)for(int j = 0 ; j < len1 ; j++)if(s1[j] == s2[p2]){p2++;if(p2 == len2)p2 = 0 , cnt ++;}return cnt / n2;}
};

n1可以达到1e6量级,len1可以达到100量级,那么总体就是1e8量级,不出意外,49个样例全部通过但是卡常,所以还是没过。

但这说明只要对暴力解法进行小优化就可以通过本题。由于在一个循环字符串中寻找另一个字符串的数目,这显然有许多的冗余匹配,那么我们不妨像kmp那样,开一个数组nxt[],nxt[i]存储从s2下标i开始和单个s1能够匹配的字符串数目(这里s2是循环的,但是统计的是和单个s1匹配的字符数目),nxt的求解可以暴力求解,由于len1,len2不超过100,所以整体预处理不超过1e4

有了nxt后,我们再在n1 * s1 上进行匹配就可以优化为O(n1)了,为什么呢?

两个字符串从0开始匹配,第一个s1匹配结束,s2下标从0变为(nxt[0] + 0)%len2,再跟第二个s1匹配,s2下标又变为 ((0 + nxt[0]) % len1 + nxt[(0 + nxt[0]) % len1]) % len1……

直接看代码会明了很多

2、复杂度

时间复杂度: O(n1) 空间复杂度:O(L)

3、代码详解

​相比于循环节的方法,该方法的代码要简洁很多,当然该方法也可以进一步优化为循环节方法,如果让你将该方法进一步优化,那么阁下又该如何应对呢?
class Solution {
public:
int nxt[101] , len1 , len2 , sum;int getMaxRepetitions(string s1, int n1, string s2, int n2) {memset(nxt , 0 , sizeof(nxt));len1 = s1.size() , len2 = s2.size() , sum = 0;for(int i = 0 ; i < len2 ; i++)for(int j = i , k = 0 ; k < len1 ; k++)if(s2[j] == s1[k])nxt[i]++ , j = (j + 1) % len2;for(int i = 0 ,j = 0 ; i < n1 ; i++)sum += nxt[j] , j = (j + nxt[j]) % len2;return sum / (len2 * n2);}
};

这篇关于LeetCode 466. 统计重复个数,循环字符串匹配优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/566091

相关文章

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

Python中使用正则表达式精准匹配IP地址的案例

《Python中使用正则表达式精准匹配IP地址的案例》Python的正则表达式(re模块)是完成这个任务的利器,但你知道怎么写才能准确匹配各种合法的IP地址吗,今天我们就来详细探讨这个问题,感兴趣的朋... 目录为什么需要IP正则表达式?IP地址的基本结构基础正则表达式写法精确匹配0-255的数字验证IP地

Mysql如何将数据按照年月分组的统计

《Mysql如何将数据按照年月分组的统计》:本文主要介绍Mysql如何将数据按照年月分组的统计方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql将数据按照年月分组的统计要的效果方案总结Mysql将数据按照年月分组的统计要的效果方案① 使用 DA

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介