【字符串】A001_统计重复个数(暴力 / 优化)

一、Problem

由 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 满足 [S2,M]
即 acbacbacbacb 中,删除任意字符后,会出现 abab 的最大个数
删除 S1 中的所有 c , 则剩下的字母由 2 个 abab 组成
所以返回 2
即 M = 2 , S1 = [S2, 2]

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

返回:
2

二、Solution

方法一:暴力匹配

枚举 s1,然后统计 s2 在 s1 出现的次数。

超时错误:这样的暴力匹配,时间复杂度为 O ( 100 n 1 ) O(100* n1) ,n1 最大为 10^6,整体计算量为 1 0 8 10^8

public int getMaxRepetitions(String s1, int n1, String s2, int n2) {
    StringBuilder sb1 = new StringBuilder(s1);
    StringBuilder sb2 = new StringBuilder(s2);
    for (int i = 1; i < n1; i++) sb1.append(s1);
    for (int i = 1; i < n2; i++) sb2.append(s2);
    
    int M = 0, k = 0;
    for (int i = 0; i < sb1.length(); i++) {
        if (sb1.charAt(i) == sb2.charAt(k)) {
            k++;
        }
        if (k == sb2.length()) {
            M++;
            k = 0;
        }
    }
    return M;
}

复杂度分析

  • 时间复杂度: O ( 100 × n 1 ) O(100 × n1)
  • 空间复杂度: O ( n ) O(n)

方法二:暴力优化

优化一:

  • 我们需要在 [s1, n1] 中 找 [s2, n2] × M,找到最大的 M。
  • 我们不必要去把 s2 拼接 n2 次,取而代之的是直接在 s 1 × n 1 s1 × n1 中找到 T 个 s2,最后返回 T n 2 \cfrac{T}{n2} 即可。
  • 还是超时…

优化二:

  • 如果 s1 剩下的字符不够 s2.length() 个的话,结束即可。
发布了714 篇原创文章 · 获赞 199 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/105625096