493. 连续子数组零尾数问题 | 豆包MarsCode AI刷题

72 阅读2分钟

连续子数组零尾数问题

问题描述

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

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

思路

要计算数组中连续子数组的数量,这些子数组的乘积末尾零的数量大于等于 x。末尾零的数量由乘积中因子2和因子5的数量决定,因为每个末尾零对应一对因子2和因子5。

预先储存每个数的因子

对于每个元素计算其包含的2和5的因子数量,分别存储起来。

双指针

使用双指针法来遍历所有可能的子数组。对于每个子数组,计算其因子2和因子5的数量,并判断是否满足条件(即因子2和因子5的最小值大于等于 x)。

时间复杂度:O(nlog(max_num))O(n\log(max\_num))

  • 对于每个数组中的元素,我们都需要计算其包含的2和5的因子数量。这一步骤需要遍历整个数组一次,并且对于每个元素,最坏的情况下需要进行O(log(num))O(log(num))次除法操作来计算因子数量(这里num是数组中的元素)。因此预处理阶段的时间复杂度为O(nlog(max_num))O(n * log(max\_num)),其中n是数组的长度,max_num是数组中最大的元素。
  • 在滑动窗口阶段,我们使用两个指针(leftright)来表示当前窗口的边界。每个指针最多遍历数组一次,因此这个阶段的时间复杂度为O(n)。在窗口内部,我们不断更新2和5的计数器,并在满足条件时更新结果。这些操作都是常数时间操作。

最终时间复杂度为O(n * log(max_num))

空间复杂度:O(n)O(n)

MOD = 10**9 + 7
    
    def count_factors(n, factor):
        """计算n中包含多少个factor因子"""
        count = 0
        while n % factor == 0:
            n //= factor
            count += 1
        return count
    
    # 预处理每个数字中的2和5的因子数量
    factors = [(count_factors(num, 2), count_factors(num, 5)) for num in a]
    
    left = 0
    count_2 = 0
    count_5 = 0
    result = 0
    
    for right in range(len(factors)):
        count_2 += factors[right][0]
        count_5 += factors[right][1]
        
        # 当前窗口内的2和5的最小值大于等于x
        while min(count_2, count_5) >= x and left <= right:
            # 更新结果
            result = (result + (len(factors) - right)) % MOD
            # 移动左边界
            count_2 -= factors[left][0]
            count_5 -= factors[left][1]
            left += 1

    return result