1.题目介绍
给定一个整数数组 nums
和一个整数 k
,请你统计并返回 该数组中和为 k
的子数组的个数。
子数组是数组中元素的连续非空序列。
1 <= nums.length <= 2 * 104
-1000 <= nums[i] <= 1000
-107 <= k <= 107
意思是,你需要在数组nums中找到所有其中连续的位置,其索引位置对应的数据和为k,
例如:数组[1,2,3,0,2],k为2,那么其中符合要求的序列就是:[2]、[0,2]、[2]。并将符合要求的序列出现的次数返回。
2.解决思路
要找出数组中所有满足要求的子数组,最通俗的解法是暴力解法,即遍历数组的每一个位置i,并计算该位置到0号索引的过程中是否有某个位置j到i的连续加和的结果为k。但是这种解法需要每次遍历节点的子节点,时间复杂度是O(n²)。我们可以在此基础上进行优化,节约掉每次遍历子节点的过程。所以我们采用前缀和 +哈希表的方式优化算法,即遍历数组将每次得出的前缀和记录在哈希表中,前缀和为key,出现次数为value。每次遍历只需要判断哈希表中是否有满足条件的key即可。

前缀和:数组nums中任何一个位置i,从nums[0]到nums[i]的连续加和。
3.解决思路
1.定义结果数count、初始化preSume记录每次的前缀和
2.初始化哈希表,其中key用来记录前缀和preSum的值,value用来记录其出现的次数
3.在哈希表中提前put一个前缀和为0的情况(用来避免当preSum = k时,前缀和为0的情况还 未遇到,preSum-k找不到0的情况)
4.遍历数组,让preSum每次对当前数据加和,这样可实现preSum的值一直是当前数组位置 的前缀和。
5.判断当前哈希表中是否存在preSum-k的key,即是否存在以当前preSum为基准,与哈希表 中某一前缀和的差=k的情况(子数组的和等于k),如果存在,则将count的值加上对应前 缀和出现的次数。
6.将本次遍历位置的前缀和在哈希表中的value+1,,getOrderDefault可兼顾不存在的情况
7.返回count
4.代码展示
java
public static Integer subarraySum(int[] nums,int k){
//定义结果数count
int count = 0;
//定义前缀和
int preSum = 0;
//定义哈希表存储前缀和以及出现的次数
HashMap<Integer, Integer> preSumCount = new HashMap<>();
//初始化预存入一个前缀和为0出现一次的情况
preSumCount.put(0,1);
//遍历数组
for (int num : nums) {
//计算每个位置的前缀和
preSum += num;
//如果哈希表存在前缀和之差为k的键,则将count加上其出现的次数
if (preSumCount.containsKey(preSum - k)) {
count += preSumCount.get(preSum - k);
}
//更新该前缀和出现的次数
preSumCount.put(preSum, preSumCount.getOrDefault(preSum, 0) + 1);
}
return count;
}
5.执行结果
在leetcode测试用例中平均耗时24ms

内存分布43.84MB
