📜  整数字符串中可被4整除的子字符串数(1)

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

整数字符串中可被4整除的子字符串数

简介

本篇介绍了如何计算整数字符串中可被4整除的子字符串数。

举例来说,对于字符串 "1248",其中的可被4整除的子字符串为 "12" 和 "48",因此可被4整除的子字符串数为 2。

解题思路

有两种常用的解题思路:

方法一:暴力枚举

最直接的方法是枚举所有子字符串,然后判断是否能被4整除。

时间复杂度为 O(n^2),可以用一个外层循环枚举子串的起点,用一个内层循环枚举子串的终点。

代码:

def countSubstrings(s: str) -> int:
    cnt = 0
    for i in range(len(s)):
        for j in range(i, len(s)):
            if int(s[i:j+1]) % 4 == 0:
                cnt += 1
    return cnt
方法二:数学归纳法

观察可被4整除的数字,它们的末两位必须是4、8、12、16、20、24、28、32、36、40、44、48、52、56、60、64、68、72、76、80、84、88 或 92。

因此,只要求出字符串中有多少个末两位为这些数字的子串,就可以得到可被4整除的子字符串数。

根据数学归纳法,假设已经知道长度为 n 的字符串中有多少个末两位为这些数字的子串,如何求长度为 n+1 的字符串呢?

首先考虑字符串中以最后一个字符结尾的子串。假设最后两位分别为 x 和 y,那么:

  1. 如果 y 不为 0,则以它为结尾的子串的末两位为 xy,这能对整个字符串的计数贡献 1;
  2. 如果 y 为 0,而 x 不为 0,则以它为结尾的子串的末两位为 10x,这能对整个字符串的计数贡献 1。

然后考虑以倒数第二个字符结尾的子串。如果这个字符是 x,那么:

  1. 如果最后一个字符是 y,那么以它为结尾的子串的末两位为 xy,这能对整个字符串的计数贡献 len(s)-1 个;
  2. 如果最后一个字符是 0,那么以它为结尾的子串的末两位为 10x,这能对整个字符串的计数贡献 1 个。

综上所述,对于每个长度为 n 的字符串,可以在 O(1) 的时间内计算长度为 n+1 的字符串中末两位为这些数字的子串个数,因此总时间复杂度为 O(n)。

代码:

def countSubstrings(s: str) -> int:
    cnt = 0
    if int(s[-2:]) % 4 == 0:
        cnt += 1
    n = len(s) - 2
    for i in range(n):
        x = int(s[i:i+2])
        y = int(s[i+1])
        if x % 4 == 0:
            cnt += i+1
        if y == 0 and x % 4 != 0:
            continue
        if (10*x+y) % 4 == 0:
            cnt += i+1
    return cnt
总结

方法一是最朴素的解法,但时间复杂度高,适合数据量不大的情况。方法二是通过数学归纳法推导出的通用方法,时间复杂度较低,适合大数据量的情况。