通常我们由前缀和来求某一段区间的和时,sum(i, j) = s[i] - s[j]
但是对于我们n=10^5或n^4的情况来说,我们枚举i和j会由n^2的时间复杂度约10^8~10^10,擦边超出了我们算法要求的时间复杂度内
所以我们可通过哈希来优化
我们要求k = s[i] - s[j]的数量,即求s[j] = s[i] - k的数量,而我们用哈希unordered_map<int, int>,key表示前缀和s[j],value表示s[j]在i之前出现的次数。然后我们求s[j]在之前出现的次数的和即可
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var subarraySum = function(nums, k) {
let res = 0;
let s = [];
s[0] = 0;
for (let i = 1; i <= nums.length; i ++) {
s[i] = s[i-1] + nums[i-1];
}
let hash = new Map();
hash.set(0, 1);
for (let i = 1; i <= nums.length; i ++) {
if (hash.has(s[i] - k)) res += hash.get(s[i] - k);
if (hash.has(s[i])) hash.set(s[i], hash.get(s[i])+1);
else hash.set(s[i], 1);
}
return res;
};