题目

image.png

思路

思路一
暴力破解,两层循环,判断每个子数组能够被k整除。


思路二
前缀和。
image.png
image.png
【LeetCode】974.和可被k整除的子数组 - 图4
【LeetCode】974.和可被k整除的子数组 - 图5
【LeetCode】974.和可被k整除的子数组 - 图6

因此,只要根据当前第j个数结尾的数组之和 的模,去找之前前缀模相同的数量,即为可被k整数的子区间的数量。
因为与mod k,余数只可能有k-1中有限情况。(比如mod 3,余数只可能有0,1,2)
所以用哈希表去维护余数modulus时,连续子区间的数量。

看代码

代码

暴力破解代码,优化求和

  1. class Solution:
  2. def subarraysDivByK(self, A: List[int], K: int) -> int:
  3. n = len(A)
  4. if not any(A):
  5. # 全零
  6. return int(n*(n+1)*0.5)
  7. tmp = []
  8. cum = []
  9. count = 0
  10. cum_sum = 0
  11. for num in A:
  12. cum.append(num)
  13. cum_sum += num
  14. tmp = cum[:]
  15. tmp_sum = cum_sum
  16. while tmp:
  17. if tmp_sum % K == 0:
  18. count += 1
  19. tmp_sum -= tmp.pop(0)
  20. return count

时间超了,通过不了全部测试用例。

  1. class Solution:
  2. def subarraysDivByK(self, A: List[int], K: int) -> int:
  3. record = {0: 1}
  4. total, ans = 0, 0
  5. for elem in A:
  6. total += elem # 当前elem结尾的区间之和
  7. modulus = total % K # 求模
  8. same = record.get(modulus, 0) # 得到之前模相同的子区间的个数
  9. ans += same # 计数器增加
  10. record[modulus] = same + 1 # 维护哈希表
  11. return ans