The key to this question is to utilise the power of prefix-sum arrays.
Example:
- for
[3, 2, 4, 5, 7, 2, 3], we can pre-compute values satisfyingnums[i] % modulo == k
- as a result, we get the array
[1, 0, 0, 1, 1, 0, 1]- however, if we want to check what the
cntis between any 2 indices, we can compute a prefix-sum array,ps_array,
- the prefix-sum array will thus be
[1, 1, 1, 2, 3, 3, 4]- then, calculate the
cntusing(ps_array[j] - ps_array[i]) % modulo == kfor indexiandjwherei < j
- note, however, that we can rewrite this equation to
(ps_array[j] - k) == ps_array[i] (mod modulo), implying that we can create a hash-map to hash the number of timesps_array[i] % modulohas appeared previously- that implies that we can just calculate
(ps_array[j] - k) % moduloto check the previous count in the hashmap
code
class Solution {
public:
long long countInterestingSubarrays(vector<int>& nums, int modulo, int k) {
unordered_map<int, int> mp;
mp[0] = 1; // for the cases, where the entire array is `cnt % modulo``
long long counter = 0;
long long ans = 0;
for (int i = 0; i < nums.size(); ++i) {
counter += (nums[i] % modulo == k);
ans += mp[(counter + modulo - k)%modulo];
++mp[counter%modulo];
}
return ans;
}
};
complexity
- Time:
O(n)wherendenotes the length of the array- Space:
O(n)
learnings
- using a
vectorinstead of anunordered_mapmakes you TLE; arrays are not always better