# 974. 和可被 K 整除的子数组

# 题目

给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。

示例
输入:A = [4,5,0,-2,-3,1], K = 5
输出:7
解释:
有 7 个子数组满足其元素之和可被 K = 5 整除:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]

# 个人题解

我们首先要知道一个原理,在这题上就是在原数组上面任何位置任何数加上n*K(n是整数),对结果不会产生影响
定义map{0:1}(边界条件),count计数,preSum来累加
通过preSum = (preSum + A[i]) % K我们可以得到余数,如果得到的余数在先前的map中出现过,那么说明这一次相加的值后累加的值满足了条件,那么我们的count即可相加一次

# 具体代码

var subarraysDivByK = (A, K) => {
  let map = { 0: 1 }   // 为了让边界情况也能适用通式
  let preSum = 0       // 供累加,初始值0
  let count = 0        // 计数
  for (let i = 0; i < A.length; i++) { // 一次遍历做完所有事
    preSum = (preSum + A[i]) % K // 前缀和累加上次的而得,再mod
    if (preSum < 0) preSum += K  // 因为负数取模还是负数,所以需要加 K
    if (map[preSum]) {      // 之前存过与当前preSum相等的key
      count += map[preSum]  // 把对应的值(出现次数)累加给count
    }
    if (map[preSum]) {      // 以前存过,出现次数+1
      map[preSum]++
    } else {                // 新存入,初始值1
      map[preSum] = 1
    }
  }
  return count              // 返回计数结果
}```