📅  最后修改于: 2023-12-03 15:26:12.668000             🧑  作者: Mango
本篇介绍了如何计算整数字符串中可被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,那么:
然后考虑以倒数第二个字符结尾的子串。如果这个字符是 x,那么:
综上所述,对于每个长度为 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
方法一是最朴素的解法,但时间复杂度高,适合数据量不大的情况。方法二是通过数学归纳法推导出的通用方法,时间复杂度较低,适合大数据量的情况。