携手创作,共同成长!这是我参与「掘金日新计划 · 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
};
最后
如果有更好的解法或者思路, 欢迎在评论区和我交流~ ღ( ´・ᴗ・` )