• 面试题466:统计重复个数(C++)


    题目地址:https://leetcode-cn.com/problems/count-the-repetitions/

    题目描述

    由 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

    解题思路

    思路1:分析题目可知,字符串S1是由n1个s1连接而成,字符串S2是由n2个s2连接而成,求满足使[S2,M]从S1获得的最大整数M,有点绕口,通俗说,即求S1中包含S2的个数M。最容易想到的方法是初始化M=0,然后遍历S1寻找S2,找到S2后M++,依次继续,直到S1遍历结束。当然,需要注意遍历的条件,即保证S2的长度应该小于等于S1的长度。不过可惜的是,这种思路导致超时问题。

    思路2:如果s2在S1中出现了N次,那么S2肯定在S1中出现了N/n2次,这里的大写表示字符串加上重复次数组成的大字符串,即字符串拼接结果。所以,我们只要算出s2出现的次数count_s2,然后除以n2,就可以得出S2在S1中出现的次数了,即可求得M。

    程序源码

    暴力(超时

    class Solution {
    public:
        int getMaxRepetitions(string s1, int n1, string s2, int n2) {
           string S1 = "", S2 = "";
            int M = 0;
            for(int i = 0; i < n1; i++) S1 += s1;
            for(int j = 0; j < n2; j++) S2 += s2;
            int k = 0;
            for(int i = 0; i < S1.size(); i++)
            {
                if(S1[i] == S2[k]) k++;
                if(k == S2.size())
                {
                    M++;
                    k = 0;
                }
            }
            return M;
        }
    };

    思路2:暴力优化

    class Solution {
    public:
        int getMaxRepetitions(string s1, int n1, string s2, int n2) {
           int s2_next_index = 0, count_s1 = 0, count_s2 = 0;
           unordered_map<int, pair<int, int>> mp;
           while(count_s1 < n1)
           {
               for(int i = 0; i < s1.size(); i++)
               {
                   if(s1[i] == s2[s2_next_index]) s2_next_index++;
                   if(s2_next_index == s2.size())
                   {
                       s2_next_index = 0; //下一轮循环
                       count_s2++;
                   }
               }
               count_s1++;
               if(mp.count(s2_next_index) == 0) mp[s2_next_index] = make_pair(count_s1, count_s2);
               else 
               {
                   int last_count_s1 = mp[s2_next_index].first;
                   int last_count_s2 = mp[s2_next_index].second;
                   int interval_s1 = count_s1 - last_count_s1;
                   int interval_s2 = count_s2 - last_count_s2;
                   int num = (n1 - count_s1) / interval_s1;
                   count_s2 += num * interval_s2;
                   count_s1 += num * interval_s1;
               }
           }
           return count_s2 / n2;
        }
    };

    参考文章

    https://www.cnblogs.com/grandyang/p/6149294.html

    https://leetcode-cn.com/problems/count-the-repetitions/solution/fang-zhao-yi-ge-da-lao-xie-de-by-paul_666/

    ----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
  • 相关阅读:
    C#异步编程
    3.TinkPHP中的模型
    Socket网络编程
    日志查看登录用户
    ssh相关的设置
    爬虫学习笔记
    python升级到3.*版本
    Redis未授权访问攻击过程与防范
    Linux重置MySQL密码
    linux下WordPress安装
  • 原文地址:https://www.cnblogs.com/wzw0625/p/12731463.html
Copyright © 2020-2023  润新知