930. Binary Subarrays With Sum
题解
这道题我之前确实没有思路。
只想到了用前缀和去求解,但是我认为前缀和求的方式是O(n^2)的算法。
这个地方包含了一层递推关系的。
goal = s[i] - s[j - 1]。对于一个固定的前缀和s[i],我们期望判断之前有多少的前缀和是s[i] - goal。所以我们可以利用一个hash表,存储所有的s[j]。
代码
class Solution {public:int numSubarraysWithSum(vector<int>& nums, int goal) {unordered_map<int, int> cnt;int res = 0;cnt[0] ++;for (int i = 1, s = 0; i <= nums.size(); i ++) {s += nums[i - 1];// s[i] - s[j - 1] = goal// s[j - 1] = s[i] - goal;res += cnt[s - goal];cnt[s] ++;}return res;}};
974. Subarray Sums Divisible by K
题解
这道题的思路和上面的题目如出一辙,也是一个前缀和的问题。
题目里其实有一些小陷阱。
比如说推出了s[i] % k == s[j] % k之后,里面有一层引申含义是,等式左右两边的数值范围均为[0, k)
利用之前元素和现在元素前缀和的关系,很快的求得最终的答案。
代码
class Solution {public:int subarraysDivByK(vector<int>& nums, int k) {vector<int> cnt(k, 0);cnt[0] ++;int res = 0;for (int i = 1, s = 0; i <= nums.size(); i ++) {s += nums[i - 1];// (s[i] - s[j]) % k = 0;// s[i] % k == s[j] % k;int idx = s % k;if (s < 0 && idx != 0) {idx += k;}res += cnt[idx];cnt[idx] ++;}return res;}};
