目录
题目
- 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。子数组是数组中元素的连续非空序列。
示例 1:
输入:nums = [1,1,1], k = 2
输出:2
示例 2:
输入:nums = [1,2,3], k = 3
输出:2
法一、暴力枚举
- 思路:两层for循环,一层遍历数组,第二层根据第一层的当前元素作为子数组的最后一个元素,往前每一步都求和一直到nums第一个元素
var subarraySum = function(nums, k) {
let cnt=0
//遍历nums数组
for(let start=0;start<nums.length;++start){
let sum=0//当前子数组和
//把当前遍历到的元素作为子数组的最后一个元素,往前求和
for(let end=start;end>=0;end--){
sum+=nums[end]
if(sum==k){
cnt++
}
}
}
return cnt
};
法二、前缀和 + 哈希表优化
- 前缀和:当前元素及其之前元素的和,可以用来求子数组和,比如:nums=[3,4,7,2,-3]则pre=[3,7,14,16,13]那么pre[4]-pre[1]=6=nums[2]+nums[3]+nums[4]
- 思路:求子数组和为k的个数,相当于求pre[i]-pre[j-1]=k的个数,可移项得pre[j-1]=pre[i]-k只需要统计pre[j-1]的个数。统计使用一个哈希表,以pre[i]作键,pre[i]出现的次数作值,最后统计哈希表中pre[j-1](或者pre[i]-k)出现的次数
var subarraySum = function(nums, k) {
// 创建一个映射,用于存储前缀和及其出现次数
const mp = new Map();
// 初始化映射,前缀和为0时的出现次数为1
mp.set(0, 1);
// 初始化计数器,记录满足条件的子数组数量
let count = 0;
// 初始化前缀和
let pre = 0;
// 遍历数组中的每一个元素
for (const x of nums) {
// 更新当前的前缀和
pre += x;
// 检查当前前缀和减去k的值是否存在于映射中
// 如果存在,说明找到了对应的子数组
if (mp.has(pre - k)) {
// 将找到的子数组数量加到计数器中
count += mp.get(pre - k);
}
// 检查当前前缀和是否已经存在于映射中
if (mp.has(pre)) {
// 如果存在,增加当前前缀和的出现次数
mp.set(pre, mp.get(pre) + 1);
} else {
// 如果不存在,初始化当前前缀和的出现次数为1
mp.set(pre, 1);
}
}
// 返回满足条件的子数组数量
return count;
};
标签:pre,前缀,nums,560,元素,mp,数组
From: https://www.cnblogs.com/lushuang55/p/18512354