前缀和+哈希优化(干货) 例题:leetcode560 和为k的数组

93 阅读1分钟

leetcode.cn/problems/su…

通常我们由前缀和来求某一段区间的和时,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;
};