LeetCode Everyday - 和为 K 的子数组

102 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情 >>

和为 K 的子数组

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 *该数组中和为 k ***的连续子数组的个数

示例1:

输入: nums = [1,1,1], k = 2
输出: 2

示例2:

输入: nums = [1,2,3], k = 3
输出: 2

提示:

  • 1 <= nums.length <= 2 * 104
  • -1000 <= nums[i] <= 1000
  • -107 <= k <= 107

解题思路:

本题就是两数之和的改版,两数之差,换汤不换药
求出每项的前缀和prefixSum,第i到第j项如果符合nums[i] + nums[i + 1] + ... + nums[j] === k,那么此子序列就符合题意,拆解下公式就是
第j项的前缀和 - 第i - 1项的前缀和 === k,则符合题意,也就是prefixSum|j| - prefixSum|i - 1| === k,这就是带前缀和的两数之差

两数之和是 a + b === k,两数之差是a - b = k,可以同样使用哈希表查找优化

时间复杂度:O(n)
空间复杂度;O(n)

概念解释

[散列表](Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的[数据结构]。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做[散列函数],存放记录的[数组]叫做[散列表]。

给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

我的答案:

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var subarraySum = function(nums, k) {
    const map = new Map()
    let prefixSum = 0
    let count = 0
    map.set(0, 1)

    for (const value of nums) {
        prefixSum += value
        if (map.get(prefixSum - k))
            count += map.get(prefixSum - k)

        if (map.has(prefixSum))
            map.set(prefixSum, map.get(prefixSum) + 1)
        else
            map.set(prefixSum, 1)
    }
    
    return count
};

最后

如果有更好的解法或者思路, 欢迎在评论区和我交流~ ღ( ´・ᴗ・` )