简单枚举:
java
class Solution {
public int subarraySum(int[] nums, int k) {
int count = 0;
for (int i = 0; i < nums.length ; i ++){
int sum = 0;
for(int j = i ; j < nums.length ;j ++){
sum += nums[j];
if(sum == k){count ++;}
}
}
return count;
}
}
同理也可以从右往左看来解答(方法二需要这个角度来解答)
java
public class Solution {
public int subarraySum(int[] nums, int k) {
int count = 0;
for (int start = 0; start < nums.length; ++start) {
int sum = 0;
for (int end = start; end >= 0; --end) {
sum += nums[end];
if (sum == k) {
count++;
}
}
}
return count;
}
}
即:
以 i 结尾和为 k 的连续子数组个数,我们需要统计符合条件的下标 j 的个数
我们可以基于上述方法利用数据结构进行进一步的优化
方法一的瓶颈:
在于对每个 i,我们需要枚举所有的 j 来判断是否符合条件(从右往左的方法一答案版本中的i、j)
前缀和 + 哈希表优化
求以 i 结尾的和为 k 的连续子数组个数
只要统计有多少个前缀和为 prei−k 的 prej 即可
前缀和:eg.第i个数的前缀和即第一个数到第i个数相加
java
public class Solution {
public int subarraySum(int[] nums, int k) {
int count = 0, pre = 0;
// map:key = 前缀和的值,value = 这个前缀和出现过多少次
HashMap < Integer, Integer > mp = new HashMap < > ();
// 初始化:前缀和=0 出现1次
mp.put(0, 1);
for (int i = 0; i < nums.length; i++) {
pre += nums[i];
//核心代码,看下面解释
if (mp.containsKey(pre - k)) {
count += mp.get(pre - k);
}
mp.put(pre, mp.getOrDefault(pre, 0) + 1);
}
return count;
}
}
难点解析:
java
if (mp.containsKey(pre - k)) {
count += mp.get(pre - k);
}
mp.put(pre, mp.getOrDefault(pre, 0) + 1);
pre - k:

pre - k 为啥是key,感觉是value更合适吧
重申:HashMap<前缀和数值, 这个前缀和出现过多少次>
pre - k不存在为啥pre存map?
map 的作用:存下当前这个前缀和,给后面的元素去查
所以put没放在else里边:二者不沾边