给定一个整数数组和一个整数 k ,请找到该数组中和为 k 的连续子数组的个数。
示例 1:
输入:nums = [1,1,1], k = 2
输出: 2
解释: 此题 [1,1] 与 [1,1] 为两种不同的情况
示例 2:
输入:nums = [1,2,3], k = 3
输出: 2
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/QTMn0o
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
举例1:nums = [1,1,1], k = 2
| nums | 1 | 1 | 1 | |
| 前缀和 | 0 | 1 | 2 | 3 |
| map的状态 | {(0,1)} | {(0,1),(1,1)} | {(0,1),(1,1),(2,1)} | {(0,1),(1,1),(2,1),(3,1)} |
| 符合要求的子数组个数 | 0 | 0 | 1 因为2-k=0,0在hashmap中存储的v键值对为(0,1) 所以count=1; | 1+1 因为3-k=1, 1存在于hashmap在存储中的键值对是(1,1) 所以count=count+1=2; |
例2:nums = [1,2,3], k = 3
| nums | 1 | 2 | 3 | |
| 前缀和 | 0 | 1 | 3 | 6 |
| map的状态 | {{0,1)} | {{0,1),(1,1)} | {{0,1),(1,1),(3,1)} | {{0,1),(1,1),(3,1)} |
| 符合要求的子数组个数 | 0 | 0 | 1 因为3-k=0 hashmap中存储的v键值对为(0,1) 所以count=1; | 2=1+1 因为6-k=3 hashmap中存储的v键值对为(3,1) 所以count=count+1; |
所以我们将前缀和与出现次数,放进hashmap。根据hashmap的特性,一下子判断是否存在这样的子数组。
- class Solution {
- public int subarraySum(int[] nums, int k) {
- //count代表了符合要求的子数组的个数
- int count=0;
- //pre代表了前缀和
- int pre=0;
- //hashmap用来存储前缀和与出现次数
- HashMap
map=new HashMap(); - //所有的数组最开始有一个前缀为0
- map.put(0,1);
- for(int i=0;i
- //计算所有的前缀和
- pre=pre+nums[i];
- //如果在nums的[i,j]区间,nums[(0-j)]的前缀和-nums[(0-i)]代表[i,j]这个区间是相加等于k的子数组
- if(map.containsKey(pre-k)){
- count=count+map.get(pre-k);
- }
- //如果出现前缀和相同的情况,出现个数增加
- map.put(pre,map.getOrDefault(pre,0)+1);
- }
- return count;
-
- }
- }