最后更新于
最后更新于
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
示例 1 :
说明 :
数组的长度为 [1, 20,000]。
数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。
暴力法是枚举出所有连续自数组, 判断是否符合条件, 遍历数组, 对于每个i
, 都要枚举所有[j, i]
这样的子数组. 优化就是通过前缀和的方法.
定义前缀和数组pre
, pre[i]
代表nums[0, 1, ..., i - 1]
的和, 这样pre[i]
可以由pre[i - 1]
递推而来. 即pre[i] = pre[i - 1] + nums[i - 1]
. pre
前缀和数组的长度为n + 1
, n
是原数组nums
的长度, pre[0]
由于没有对应的前缀, 我们定义值为0.
那么每个连续子数组的和k
就可以由前缀和数组得到: k = pre[i + 1] - pre[j]
, 代表[j, i]
子数组之和. 因此在遍历到i
位置时, 计算出前缀和pre[i + 1]
的同时, 我们也可以计算出当前位置如果要满足子数组和k
对应的pre[j]
, 而pre[j] = pre[i + 1] - j
, 因此, 我们下一步的目标就是寻找值为pre[j] = pre[i + 1] - j
的前缀和位置由多少.
因此, 为了搜索的快捷, 不会使用数组去存储前缀和, 而是使用哈希表. key值为前缀和值, value是当前前缀和对应的出现次数. 因此只需要遍历一次数组, 就能够得到满足条件的连续子数组的个数了.