题目地址:
https://leetcode.com/problems/subarray-sums-divisible-by-k/
给定一个长 n n n的数组 A A A,再给定一个大于 1 1 1的正整数 k k k,问其有多少个非空子数组和是 k k k的倍数。
求一下 A A A的前缀和模 k k k数组 c c c,即 c [ i ] = ( ∑ k = 0 i − 1 A [ k ] ) m o d k c[i]=(\sum_{k=0}^{i-1}A[k])\mod k c[i]=(∑k=0i−1A[k])modk,接着遍历 c c c,并开一个哈希表,key是模 k k k的值,value是模 k k k的值是key的前缀有多少个。这样遍历到 c [ i ] c[i] c[i]的时候,查一下哈希表key为 c [ i ] c[i] c[i]的value,就知道了以 A [ i − 1 ] A[i-1] A[i−1]为右端点的和是 k k k的倍数的子数组有多少个了,累加即可。代码如下:
class Solution {
public:
int subarraysDivByK(vector<int>& a, int k) {
int res = 0;
unordered_map<int, int> mp;
mp[0] = 1;
for (int i = 0, s = 0; i < a.size(); i++) {
s = (s + a[i] % k + k) % k;
res += mp[s];
mp[s]++;
}
return res;
}
};
时间复杂度 O ( n ) O(n) O(n),空间 O ( k ) O(k) O(k)。