统计重复个数--循环结剪枝

算法 专栏收录该内容
109 篇文章 12 订阅

0x01.问题

由 n 个连接的字符串 s 组成字符串 S,记作 S = [s,n]。例如,["abc",3]=“abcabcabc”。

如果我们可以从 s2 中删除某些字符使其变为 s1,则称字符串 s1 可以从字符串 s2 获得。例如,根据定义,“abc” 可以从 “abdbec” 获得,但不能从 “acbbe” 获得。

现在给你两个非空字符串 s1 和 s2(每个最多 100 个字符长)和两个整数 0 ≤ n1 ≤ 10^6 和 1 ≤ n2 ≤ 10^6。现在考虑字符串 S1 和 S2,其中 S1=[s1,n1] 、S2=[s2,n2]

请你找出一个可以满足使 [S2,M]S1 获得的最大整数 M 。

示例: 输入: s1 =“acb”,n1 = 4 s2 =“ab”,n2 = 2
返回: 2

public int getMaxRepetitions(String s1, int n1, String s2, int n2) 

0x02.详细分析

初看问题,发现有些晦涩难懂,再读。。。

抓住问题的关键:

  • 字符串 S1n1个相同的字符串s1构成。
  • 字符串 S2n2个相同的字符串s2构成。
  • 题目要求的是,字符串S2 最多S1出现几次。
  • 其中,这个出现指的是只要按照顺序在S1里面出现就行,不需要一定相连。
  • 比如:字符串S2='ASCASC'在字符串S1='ADSFCADSFC'最多出现了一次。

弄清楚了问题的本质后,开始想办法去解决这个问题,首先,第一条思路,最原始,最暴力的思路:

  • 遍历S1,看在里面最多能找出多少个S2

这条思路直击问题的本质,毫无疑问是可以解决这个问题的,但是作用并不大。

以为注意到n可能非常的大,所以,如果要遍历完整个的字符串,肯定效率不高。

那么我们就要想办法从中去消减时间,也就是俗称的 剪枝

如何剪起呢?

我们一刚开始就想生成S1S2,但是我们似乎忘了点什么,S1S2都是高度循环的字符串呀,如果我们直接拼起来,那么我们就忽略循环字符串的这个特性,就当做了一个普通的字符串来处理,这也是我们这条思路得弊端。

说明,问题的关键还是要利用这个循环的特性。

我们设想一下,S1是高度循环的,S2也是高度循环的,最终要找的是S2S1里面出现的次数,如果我们知道在S1里面有这样一个特殊的字符串:

  • 它包含了整个的S2,或者S2的一小部分相同的字符串,并且,它在S1里面循环出现。

如果有这样一个字符串,那么,我们后面的计算,只要做简单的乘法运算,即可算出中间一大段的数量,这样省去了非常多的时间。

然后,问题就来到了如何去寻找这样的字符串,(这样的字符串其实叫做循环结)

  • 我们可以维护一个哈希表,索引是s2里面的一个下标,代表当前匹配到s2里面的index位,而此时匹配的状态,记录当前匹配到第cous1s1,第cous2s2
  • 如果相同的下标在哈希表内重复出现了,说明找到了一个循环结。
  • 说明:说明再两次匹配中,匹配到相同的s2,所以出现了循环结。

找到循环结后,计算出中间一大段的cous1cous2,最后整理答案:

  • 模拟cir1表示,这个循环结占据多少个s1
  • 模拟cir2表示,这个循环结占据多少个s2
  • 那么匹配s1的个数cous1+=cir1*((n1-cous1)/cir1)
  • 那么匹配s2的个数cous2+=cir2*((n1-cous1)/cir1)
  • 最终返回的是cous2/n2,表示总共匹配的s2的个数与S2里面s2的个数之比。

0x03.解决代码–循环结剪枝

class Solution {
public int getMaxRepetitions(String s1, int n1, String s2, int n2) 
    {
        if(n1==0||n2==0) return 0;
        char[] c1=s1.toCharArray();
        char[] c2=s2.toCharArray();
        int len1=s1.length();
        int len2=s2.length();
        int cous1=0;//记录遍历s1的次数
        int cous2=0;//记录遍历s2的次数
        int index=0;//记录遍历s2的下标
        //哈希表记录每一次遍历s1后,对于index而言此时匹配的状态值
        Map<Integer,int[]> hash=new HashMap<>();
        while(cous1<n1){
            //遍历s1
            for(int i=0;i<len1;i++){
                //匹配s2中的字符
                if(c1[i]==c2[index]){
                    index++;
                    //匹配到s2的末尾
                    if(index==len2){
                        index=0;
                        cous2++;
                    }
                }
            }
            cous1++;
            
            if(!hash.containsKey(index)){
                //未出现相同状态,直接存入哈希表
                hash.put(index,new int[]{cous1,cous2});
            }else{
                //出现相同状态,说明出现了循环结
                int[] cou=hash.get(index);
                //这个循环结在s1里面占多少个相同字段数
                int cir1=cous1-cou[0];
                //这个循环结在s2里面占多少个相同字段数
                int cir2=cous2-cou[1];
                // s2中占的相同字段数  *  剩下循环的次数        
                cous2+=cir2*((n1-cous1)/cir1);
                // s1中占的相同字段数  *  剩下循环的次数
                cous1+=cir1*((n1-cous1)/cir1);
            }
        }
        //最终的答案是匹配的s2的总次数/s2的总重复数
        return cous2/n2;
    }
}

ATFWUS --Writing By 2020–04-19

  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

# 国家集训队论文列表(1999-2017) ## 1999 陈 宏 -《数据构的选择与算法效率——从IOI98试题PICTURE谈起》 来煜坤 -《把握本质,灵活运用——动态规划的深入探讨》 齐 鑫 -《搜索方法中的剪枝优化》 邵 铮 -《数学模型的建立、比较和应用》 石润婷 -《隐蔽化、多维化、开放化──论当今信息学竞赛中数学建模的灵活性》 杨 帆 -《准确性、全面性、美观性——测试数据设计中的三要素》 周咏基 -《论随机化算法的原理与设计》 ## 2000 陈 彧 《信息学竞赛中的思维方法》 方 奇 《动态规划》 高寒蕊 -《递推关系的建立及在信息学竞赛中的应用》 郭 一 -《数学模型及其在信息学竞赛中的应用》 江 鹏 -《探索构造法解题模式》 李 刚 -《动态规划的深入讨论》 龙 翀 -《解决空间规模问题的几种常用的存储构》 骆 骥 -《数学模型的建立和选择》 施 遥 -《人工智能在围棋程序中的应用》 肖 洲 -《数据构的在程序设计中的应用》 谢 婧 -《规模化问题的解题策略》 徐 串 -《论程序的调试技巧》 徐 静 -《图论模型的建立与转化》 杨江明 -《论数学策略在信息学问题中的应用》 杨 培 -《非最优化算法初探》 张 辰 -《动态规划的特点及其应用》 张 力 -《类比思想在解题中的应用》 张一飞 -《冗繁削尽留清瘦——浅谈信息的充分利用》 ## 2001 高寒蕊 -《从圆桌问题谈数据构的综合运用》 符文杰 -《Pólya原理及其应用》 高 岳 -《中等硬度解题报告》 江 鹏 -《从一道题目的解法试谈网络流的构造与算法》 刘汝佳 -《搬运工问题的启示》 李益明 -《计算几何的相关问题》 李 源 -《树的枚举》 骆 骥 -《由"汽车问题"浅谈深度搜索的一个方面——搜索对象与策略的重要性》 毛子青 -《动态规划算法的优化技巧》 俞 玮 -《基本动态规划问题的扩展》 张一飞 -《求N!的高精度算法》 ## 2002 戴德承 -《退一步海阔天空——"目标转化思想"的若干应用》 方 奇 -《浅谈必要条件的应用》 符文杰 -《排序网络》 何江舟 -《用高斯消元法解线性方程组》 何 林 -《猜想及其应用》 黄 芸 -《POI0110 跳舞蝇》 金 恺 -《浅谈网络流算法的应用》 李澎煦 -《半平面交的算法及其应用》 李 睿 -《二分法与统计问题》 骆 骥 -《浅析解 "对策问题" 的两种思路——从《取石子》问题谈起》 孙方成 -《偶图的算法及应用》 孙林春 -《让我们做得更好——从《Parity》的解法谈程序的优化》 王知昆 -《搜索顺序的选择》 许智磊 -《二分,再二分!――从Mobiles(IOI 2001)一题看多重二分》 杨旻旻 -《构造法——解题的最短路径》 张家琳 -《多项式乘法》 张 宁 -《遗传算法的特点及其应用》 张一飞 -《由感性认识到理性认识——透析一类搏弈游戏的解答过程》 周文超 -《树构在程序设计中的运用》 ## 2003 方 奇 -《染色法和构造法在棋盘上的应用》 高正宇 -《答案只有一个——浅谈问答式交互问题》 何 林 -《一类称球问题的解法》 侯启明 -《信息论在信息学竞赛中的简单应用》 姜尚仆 -《模线性方程的应用——用数论方法解决整数问题》 金 恺 -《探寻深度优先搜索中的优化技巧——从正方形剖分问题谈起》 雷环中 -《果提交类问题》 林希德 -《求最大重复子串》 刘才良 -《平面图在信息学中的应用》 刘一鸣 -《一类搜索的优化思想——数据有序化》 陆可昱 -《长方体体积并》 饶向荣 -《病毒的DNA——剖析一道字符匹配问题解析过程》 邵烜程 -《数学思想助你一臂之力》 王知昆 -《浅谈用极大化思想解决最大子矩形问题》 伍 昱 -《由对称性解2-SAT问题》 项荣璟 -《充分利用问题性质——例析动态规划的"个性化"优化》 许智磊 -《浅谈补集转化思想在统计问题中的应用》 张 宁 -《猜数问题的研究》 张云亮 -《论对算法的选择》 周 源 -《浅析"最小表示法"思想在字符串循环同构问题中的应用》 ## 2004 何 林 -《信息学中守恒法的应用》 胡伟栋 -《减少冗余与算法优化》 金 恺 -《极限法——解决几何最优化问题的捷径》 李锐喆 -《细节——不可忽视的要素》 鬲 融 -《浅谈特殊穷举思想的应用》 周 源 -《浅谈数形合思想在信息学竞赛中的应用》 朱晨光 -《优化,再优化!》 肖 天 -《"分层图思想"及其在信息学竞赛中的应用》 汪
©️2021 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值