连续子数组零尾数问题

50 阅读2分钟

解题思路

问题理解

我们需要计算数组中连续子数组的数量,这些子数组的乘积末尾零的数量大于等于给定的 x。末尾零的数量取决于乘积中因子 2 和 5 的数量,因为 10 是 2 和 5 的乘积。

数据结构选择

我们可以使用两个数组来记录每个位置之前因子 2 和 5 的累积数量。这样我们可以通过前缀和的方式快速计算任意子数组中因子 2 和 5 的数量。

算法步骤

  1. 预处理:遍历数组,计算每个位置之前因子 2 和 5 的累积数量。

  2. 计算子数组:使用双指针或滑动窗口的方式,计算满足条件的子数组数量。

  3. 取模:由于结果可能非常大,每次计算后对 10^9 + 7 取模。

    public class Main {
    public static int solution(int[] a, int x) {
    int MOD = 1000000007;
    int n = a.length;
    
    // 预处理:计算每个位置之前因子 2 和 5 的累积数量
    int[] count2 = new int[n + 1];
    int[] count5 = new int[n + 1];
    
    for (int i = 0; i < n; i++) {
        count2[i + 1] = count2[i] + countFactor(a[i], 2);
        count5[i + 1] = count5[i] + countFactor(a[i], 5);
    }
    
    int result = 0;
    
    // 计算满足条件的子数组数量
    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {
            int factors2 = count2[j + 1] - count2[i];
            int factors5 = count5[j + 1] - count5[i];
            if (Math.min(factors2, factors5) >= x) {
                result = (result + 1) % MOD;
            }
        }
    }
    
    return result;
    }
    
    // 辅助函数:计算一个数中某个因子的数量
    private static int countFactor(int num, int factor) {
    int count = 0;
    while (num % factor == 0) {
        num /= factor;
        count++;
    }
    return count;
    }
    
    public static void main(String[] args) {
    System.out.println(solution(new int[]{5, 2, 3, 50, 4}, 2) == 6);
    System.out.println(solution(new int[]{10, 5, 2, 1}, 3) == 0);
    System.out.println(solution(new int[]{25, 4, 8}, 1) == 2);
    }
    }
    ### 关键步骤解释
    
  4. 预处理count2 和 count5 数组分别记录每个位置之前因子 2 和 5 的累积数量。

  5. 计算子数组:通过双层循环遍历所有可能的子数组,计算每个子数组中因子 2 和 5 的数量,并判断是否满足条件。

  6. 取模:每次计算结果后对 10^9 + 7 取模,防止溢出。

提示

  • 你可以先实现 countFactor 函数来计算一个数中某个因子的数量。
  • 然后完善 solution 函数中的预处理和子数组计算部分。
  • 最后,确保在 main 函数中测试你的实现是否正确。