📌  相关文章
📜  重复连接子字符串的 N 长度二进制字符串的计数(1)

📅  最后修改于: 2023-12-03 15:28:31.766000             🧑  作者: Mango

重复连接子字符串的 N 长度二进制字符串的计数

介绍

给定一个长度为 n 的二进制字符串 s,如果存在一个长度为 kk 为正整数)的子字符串 t,使得 t 重复连接起来可以得到 s,那么称 ts 的一个重复连接子字符串。

例如,二进制字符串 1010 中,101010 是它的重复连接子字符串,而 1100 不是它的重复连接子字符串。

现在,给定一个二进制字符串 s 和一个正整数 N,计算长度为 N 的二进制字符串,有多少种可以是 s 的重复连接子字符串。

思路

首先,我们可以将字符串 s 按照长度为 N 分割成若干个子字符串。然后考虑对于每一个子字符串,如何判断它是否是可以由某个重复连接子字符串重复得到的。

对于一个长度为 k 的重复连接子字符串,它可以重复连接得到长度为 N 的字符串,当且仅当满足以下两个条件:

  1. Nk 的倍数;
  2. 重复连接的次数(设为 m)满足 $1 \leq m \leq \frac{N}{k}$。

因此,我们可以枚举所有可能的 k,然后计算它对应的可能的 m 的个数。

具体来讲,对于每个 k,我们可以计算出 k 的所有倍数,然后判断它们是否都是 s 的子串,如果是,根据上述条件计算出对应的可能的 m 的个数,累加到最终的答案中。

代码
def count_binary_string(s: str, N: int) -> int:
    n = len(s)
    cnt = 0
    for k in range(1, N + 1):
        if n % k == 0:
            m_max = n // k
            for m in range(1, m_max + 1):
                t = s[(m - 1) * k:m * k]
                if s.count(t) != m:
                    break
            else:
                cnt += 1
    return cnt
复杂度

时间复杂度为 $O(N^3 \log n)$,其中 $N$ 为解空间的大小,即可能的重复连接子字符串的数量;$\log n$ 是计算子字符串个数的复杂度。

空间复杂度为 $O(n)$,即存储二进制字符串的空间。