题目描述:
给定一个整数数组和一个整数 k
,你需要找到该数组中和为 k
的连续的子数组的个数。
示例 1:
1 | 输入:nums = [1,1,1], k = 2 |
说明:
- 数组的长度为
[1, 20000]
。 - 数组中元素的范围是
[-1000, 1000]
,且整数k
的范围是[-1e7, 1e7]
。
链接:
https://leetcode-cn.com/problems/subarray-sum-equals-k
题目分析
刚看到这道题目的时候以为又是经典的滑动窗口问题,小于 k 增大窗口,大于 k 缩小窗口,后来眉头一皱发现事情并不简单,数组中元素可以是负的,那就不能使用滑动窗口了。
这道题目要寻找数组中某一个区间的和为 k
,发现和前几天做的题 Leetcode 437.路径总和 III 道理是完全一样的。那道题中我们把 DFS 遍历的那段路径视为一个数组,然后利用前缀和快速找到和为 target
的区间数量,使用一个哈希表存储前缀和,用前缀和作为 key,数量作为 value。
对每一个位置的前缀和 sum
,寻找前缀和为 sum-k
的个数,那么它们所夹的区间就是和为 k
的区间,将数量添加到结果中即可。然后再更新前缀和哈希表,将当前的前缀和添加进去。需要注意的是,我们需要将前缀和为 0 的数量初始化为 1,表示没有选择数组中任何数时的前缀和为 0。
1 | class Solution { |
时间复杂度:$O(n)$,其中 $n$ 是数组的大小。我们只对数组进行了一次遍历,查找哈希表并更新前缀和,而查找和插入哈希表的时间复杂度都是 $O(1)$。
空间复杂度:$O(n)$,其中 $n$ 是数组的大小。我们需要一个哈希表来存储前缀和,最大的大小就是数组的大小。