用了prefix sum的思想,之前没用过,感觉很难
/**
* Runtime: 18 ms, faster than 56.05%
* Memory Usage: 42.9 MB, less than 35.03%
*/
class Solution {
public int subarraysDivByK(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap(); // prefixSum, cnt
map.put(0, 1);
int count = 0, prefixSum = 0;
for (int i : nums) {
// prefixSum表示从第一个元素到当前元素的和,比k的倍数大了多少
prefixSum = (i + prefixSum) % k;
if (prefixSum < 0) { // 把范围控制在0~k,不要出现负数
prefixSum += k;
}
// 在map中找之前有多少个也比k的倍数大prefixSum的,每一个和当前部分相减都是一个有效连续子区间
int preCnt = map.getOrDefault(prefixSum, 0);
count += preCnt;
map.put(prefixSum, preCnt + 1); // 更新map中比k的倍数大prefixSum的前缀序列个数
}
return count;
}
}