leetcode解题之统计重复个数

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

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

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

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

示例:

输入:
s1 ="acb",n1 = 4
s2 ="ab",n2 = 2

返回:
2

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-the-repetitions
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

首先要理解题意:S1是由n1个s1组成,S2由n2个s2组成,题中的意思是S1中有多少个S2,比如示例中的S1=“acbacbacbacb”,S2=“abab”,虽然读懂了,但是做起来是没有那么容易的,使用暴力解法是会超时的,所以就抄了官方的解题思路学习一下,简单的理解就是寻找循环节,让后计算循环节的个数

class Solution {
    public int getMaxRepetitions(String s1, int n1, String s2, int n2) {
     int s1Count = 0,s2Count=0;//找循环节时记录以查找过的s1和s2的个数
     int index = 0;//查找完s1(s1处于末尾)时s2处于的索引位置,用它的重复出现来标识是否出现循环节
     Map<Object,int[]> map = new HashMap<>();//保存循环节中的相关信息
     while(true){
         s1Count++;
         for(char c:s1.toCharArray()){//遍历s1
            if(c==s2.charAt(index)){
                index++;
            }
            if(index==s2.length()){
                s2Count++;
                index = 0;
            }
         }
         if(map.containsKey(index)){//找到循环节
            int s1CountInLoop = s1Count-map.get(index)[0];//循环节中s1的数量
            int s2CountInLoop = s2Count-map.get(index)[1];//循环节中s2的数量
            map.put("inLoop",new int[]{s1CountInLoop,s2CountInLoop});
            break;//跳出循环
         }else{
             map.put(index,new int[]{s1Count,s2Count});//保存查找过的s1,s2数量
         }
     }
     int ans = map.get(index)[1]+(n1-map.get(index)[0])/map.get("inLoop")[0]*map.get("inLoop")[1];//到循环节结束是一共有多少个s2;
     int surplusS1Count = (n1-map.get(index)[0])%map.get("inLoop")[0];//剩余的s1的数量
        while(surplusS1Count>0){
            surplusS1Count--;
            for(char c:s1.toCharArray()){
                if(c==s2.charAt(index)){
                    index++;
                }
                if(index==s2.length()){
                    ans++;
                    index=0;
                }
            }
        }
        return ans/n2;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值