连续子数组零尾数问题

99 阅读2分钟

问题描述

小F正在研究一个数组,并想要计算出其中的连续子数组的某种特性。给定一个整数数组,你需要编写一个函数来返回乘积末尾零的数量大于等于 x 的连续子数组的数量。

由于答案可能非常大,你需要将结果对 10^9 + 7 取模后再返回。

问题理解

我们需要计算一个整数数组中,乘积末尾零的数量大于等于 x 的连续子数组的数量。乘积末尾零的数量取决于因子2和因子5的数量,因为每个零对应一对因子2和因子5。

数据结构选择

  1. 前缀和数组:我们使用两个前缀和数组 prefix2 和 prefix5 来记录从数组开始到当前位置的因子2和因子5的累积数量。

算法步骤

  1. 计算每个数的因子2和因子5的数量

    • 对于数组中的每个元素,计算它包含的因子2和因子5的数量。
    • 使用 count_factors 函数来实现这一点。
  2. 填充前缀和数组

    • 遍历数组,将每个元素的因子2和因子5的数量累加到前缀和数组中。
  3. 统计符合条件的子数组

    • 使用双层循环遍历所有可能的子数组。
    • 对于每个子数组,通过前缀和数组计算因子2和因子5的数量。
    • 计算末尾零的数量,并统计符合条件的子数组数量。

代码实现

def solution(a: list, x: int) -> int: MOD = 10**9 + 7

# 计算每个数包含的因子2和因子5的数量
def count_factors(num):
    count2, count5 = 0, 0
    while num % 2 == 0:
        num //= 2
        count2 += 1
    while num % 5 == 0:
        num //= 5
        count5 += 1
    return count2, count5

# 初始化前缀和数组
prefix2 = [0] * (len(a) + 1)
prefix5 = [0] * (len(a) + 1)

# 填充前缀和数组
for i in range(len(a)):
    count2, count5 = count_factors(a[i])
    prefix2[i + 1] = prefix2[i] + count2
    prefix5[i + 1] = prefix5[i] + count5

# 统计符合条件的子数组数量
result = 0
for i in range(len(a)):
    for j in range(i, len(a)):
        # 计算子数组 [i, j] 的因子2和因子5的数量
        count2 = prefix2[j + 1] - prefix2[i]
        count5 = prefix5[j + 1] - prefix5[i]
        # 计算末尾零的数量
        zeros = min(count2, count5)
        # 如果末尾零的数量大于等于 x,则增加结果
        if zeros >= x:
            result = (result + 1) % MOD

return result

if name == 'main': print(solution(a = [5, 2, 3, 50, 4], x = 2) == 6) print(solution(a = [10, 5, 2, 1], x = 3) == 0) print(solution(a = [25, 4, 8], x = 1) == 2)